侧边栏壁纸
博主头像
太上问情 博主等级

人非太上,岂能忘情。

  • 累计撰写 17 篇文章
  • 累计创建 9 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

Python学习笔记

太上问情
2024-12-01 / 0 评论 / 0 点赞 / 25 阅读 / 0 字 / 正在检测是否收录...

起步

Python目前有两个版本,Python2和Python3,两个版本并不兼容。我们需要检查我们系统安装的Python环境版本,确保开发时使用的版本是我们想要的。

[!NOTE]

本笔记基于Python3学习

检查开发环境

在控制台输入python可以查看是否安装了Python,并查看系统默认使用的Python版本。如果系统默认版本是python2,则可以在控制台输入python3查看Python3是否已经安装。

[root@VM-8-10-centos ~]# python
Python 2.7.5 (default, Nov 14 2023, 16:14:06) 
[GCC 5.8.5 20150623 (Red Hat 5.8.5-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 

运行python程序

Python自带了一个在终端窗口中运行的解释器,让无需保存并运行整个程序就能尝试运行Python代码片段,在控制台输入python回车出现三个箭头之后,就可以输入代码了,回车就会执行并在下一行返回执行结果。

[!TIP]

《Python编程从入门到实践》告诉我,接触一门新语言时,编写的第一个程序是打印“Hello world!”会带来好运。但是我不确定我几年前使用Python写的第一个程序是不是打印“Hello world!”了……

print("Hello world!")

在各个不同环境安装python

Python初学者在不同系统上安装Python的保姆级指引

1 变量

变量是计算机程序中的一个标识符,用来存储数据。变量将数据与名称关联,使得程序能够引用和操作这些数据。在 Python 中,变量的使用非常灵活,它不需要显式声明数据类型,Python 会自动推导类型。

1.1 变量概述

变量声明

在 Python 中,变量无需显式声明类型。Python 会根据赋给变量的值自动确定其类型。只需要通过赋值操作创建变量。

示例:

x = 10        # x 是整数
name = "Alice" # name 是字符串
height = 5.6   # height 是浮点数

变量命名规则

Python 对变量命名有一定的规定,下面是一些重要的规则:

规则

  • 字母、数字、下划线:变量名只能包含字母、数字和下划线。
  • 不能以数字开头:变量名不能以数字开头。
  • 区分大小写varVar 被视为不同的变量。
  • 不能使用保留字:如 ifelse 等保留字不能作为变量名。

合法的变量名:

x = 10
name = "Alice"
_age = 25
total_Amount = 1000

非法的变量名:

1variable = 10    # 错误,不能以数字开头
if = 5            # 错误,'if' 是保留字

变量类型

Python 是动态类型语言,这意味着变量类型是由值决定的,可以在程序运行过程中更改变量类型。

变量类型自动推导

Python 会自动根据变量赋值的内容推导出数据类型。例如,如果将 10 赋给变量 x,Python 会自动将 x 视为整数类型。

x = 10    # x 是整数类型
x = "Hello"  # x 变为字符串类型

常见的变量类型

  • 整数(int):表示没有小数部分的数字。
  • 浮点数(float):表示有小数部分的数字。
  • 字符串(str):表示一串字符。
  • 布尔值(bool):表示真或假。

常量

Python 本身没有常量类型,但通常使用全大写字母来表示常量。这是编程中约定的写法,提醒程序员这些值不应修改。

示例:

PI = 3.14159   # 常量
MAX_VALUE = 100

1.2 变量的作用域

在 Python 中,变量的作用域定义了它能在哪些地方访问。常见的作用域有局部作用域和全局作用域。

局部作用域与全局作用域

  • 局部作用域:在函数或方法内定义的变量只在该函数内有效。
  • 全局作用域:在函数外部定义的变量在整个程序中都可以访问。

示例:

# 全局变量
x = 10

def func():
    # 局部变量
    y = 20
    print(x)  # 可以访问全局变量 x
    print(y)  # 可以访问局部变量 y

func()

作用域的层级

Python 中有一个 LEGB 规则,表示变量查找的顺序是:Local (局部) -> Enclosing (闭包) -> Global (全局) -> Built-in (内置)

示例:

x = 10  # 全局变量

def outer():
    x = 20  # 外部作用域的变量
    def inner():
        x = 30  # 局部作用域的变量
        print(x)
    inner()

outer()  # 输出:30

1.3 变量类型转换

Python 提供了内置的类型转换函数,可以将不同的数据类型转换成其他类型。

类型转换函数

  • int():将其他类型转换为整数。
  • float():将其他类型转换为浮点数。
  • str():将其他类型转换为字符串。

示例:

x = "10"
y = int(x)  # 将字符串 "10" 转换为整数
z = float(x)  # 将字符串 "10" 转换为浮点数

print(y)  # 输出:10
print(z)  # 输出:10.0

1.4 多重赋值

Python 允许同时给多个变量赋值,这种特性使得代码更简洁。

多重赋值的语法

Python 允许通过逗号分隔的方式同时为多个变量赋值。

示例:

a, b, c = 1, 2, 3  # 同时为 a, b, c 赋值
print(a, b, c)  # 输出:1 2 3

1.5 变量的引用与内存

在 Python 中,变量存储的是对象的引用(而不是直接存储值)。对于不可变类型,变量只保存值的副本,而对于可变类型,变量保存的是对象的引用。

不可变类型与可变类型

不可变类型

不可变类型(如整数、字符串、元组)在赋值后不能被修改。

示例:

a = 10
b = a  # b 引用 a 的值
a = 20  # 改变 a 的值

print(a)  # 输出:20
print(b)  # 输出:10

可变类型

可变类型(如列表、字典)在赋值后,多个变量可能会引用同一个对象。

示例:

lst1 = [1, 2, 3]
lst2 = lst1  # lst2 引用 lst1
lst1.append(4)

print(lst1)  # 输出:[1, 2, 3, 4]
print(lst2)  # 输出:[1, 2, 3, 4]

1.6 Python 的垃圾回收

Python 使用自动垃圾回收机制来管理内存。当对象的引用计数变为零时,Python 会自动释放该对象的内存。

引用计数与垃圾回收

Python 的垃圾回收机制基于引用计数。每个对象都维护一个引用计数,当没有任何引用指向该对象时,内存会被释放。

示例:

a = [1, 2, 3]
b = a
del a  # 删除 a 引用

# 由于 b 仍然引用列表对象,内存不会立即释放

2 数值类型

Python 中的数值类型用于表示数字。Python 提供了几种不同的数值类型,主要包括:整数int)、浮点数float)和复数complex)。这些类型都可以进行算术运算,但每种类型的适用场景不同。

2.1 整数(int

整数类型int)用于表示没有小数部分的数值。它们可以是正数、负数或零。

[!IMPORTANT]

Python 的整数类型是动态大小的,意味着整数的大小仅受到计算机内存的限制,而不像其他语言中通常有大小限制。

特点

  • 可以表示非常大的整数,不会因为数字过大而溢出。
  • 整数支持常见的算术运算(加、减、乘、除等)。

示例

x = 42       # 正整数
y = -7       # 负整数
z = 0        # 零

常见运算

sum = 10 + 5      # 加法
diff = 10 - 3     # 减法
prod = 4 * 5      # 乘法
quotient = 20 / 4 # 除法,结果为浮点数 5.0

2.2 浮点数(float

浮点数类型float)用于表示带小数的数值。浮点数广泛用于需要表示精确小数的场景,比如计算机图形学、物理模拟等。Python 使用 IEEE 754 标准来存储浮点数。

特点

  • 浮点数可以表示非常大的或非常小的数,但由于有限的存储空间,它们可能会有精度损失。
  • 适用于计算涉及小数部分的数值,如科学计算和货币计算。

示例

a = 3.14159    # 圆周率
b = -2.75      # 负浮点数
c = 0.0        # 零浮点数

常见运算

result = 3.14 * 2        # 乘法
quotient = 5.0 / 2.0     # 浮点除法

2.3 复数(complex

复数类型complex)用于表示复数,复数由一个实部和一个虚部组成,虚部以 j(或 J)表示。

特点

  • 复数的实部和虚部都可以是浮点数或整数。
  • 复数常用于科学计算,尤其是在电气工程、信号处理等领域。

示例

c1 = 3 + 4j    # 复数,实部为 3,虚部为 4
c2 = -1 + 2j   # 负复数,实部为 -1,虚部为 2

常见运算

sum = (3 + 4j) + (1 + 2j)   # 复数相加
product = (3 + 4j) * (1 - 2j) # 复数相乘

3 字符串与布尔类型

3.1 字符串(str

字符串类型str)用于表示文本数据。字符串是字符的序列,可以包含字母、数字、符号、空格等。Python 中的字符串是不可变的,这意味着一旦创建,就无法修改其内容。

特点

  • 可以通过索引来访问字符串中的单个字符(从 0 开始)。
  • 支持切片操作(通过指定起始和结束索引来提取子字符串)。
  • 可以用单引号 (') 或双引号 (") 来创建字符串。
  • 字符串是不可变的,即字符串内容一旦创建后,不能修改其中的单个字符或部分内容。

示例

name = "Alice"          # 字符串类型(双引号)
message = 'Hello!'      # 字符串类型(单引号)
greeting = "Hello, " + name  # 字符串连接

常见操作

length = len("Hello")           # 获取字符串长度
char = "Hello"[1]               # 获取字符串中索引为 1 的字符,结果为 "e"
substring = "Hello"[1:4]        # 获取字符串切片,结果为 "ell"
upper = "hello".upper()         # 转为大写字母,结果为 "HELLO"

转义字符

使用反斜杠(\)可以在字符串中插入特殊字符,例如换行符、制表符、引号等:

escaped_str = "Hello\nWorld!"  # 换行
quote = 'He said, "Hello!"'    # 引号

3.2 布尔类型(bool

布尔类型bool)只有两个值:TrueFalse。布尔类型广泛用于条件判断、逻辑运算和控制结构中(如 if 语句)。Python 中的布尔类型实际上是 int 类型的子类,True 的值为 1,False 的值为 0。

特点

  • 主要用于表示逻辑状态(真与假)。
  • 可以通过比较操作或逻辑运算(如 and, or, not)来获取布尔值。
  • TrueFalse 是 Python 的关键字。

示例

is_active = True        # 布尔值 True
has_permission = False  # 布尔值 False

常见运算

result = (10 > 5)   # 比较运算,结果为 True
not_result = not True  # 逻辑运算,结果为 False
and_result = True and False  # 逻辑运算,结果为 False

与其他数据类型的关系

  • 在 Python 中,0 被视为 False,而非零的数值、非空的字符串、非空的列表等都被视为 True
bool(0)           # False
bool(1)           # True
bool("")          # False
bool("Hello")     # True
bool([1, 2, 3])    # True

4 列表

列表由一系列按特定顺序排列的元素组成。在Python中,用方括号([])来表示列表,并用逗号来分隔其中的元素。

names = ['太上问情', 'test1', 'test2']

6.1 访问列表元素

列表是有序集合,因此要访问列表的任何元素,只需将该元素的位置或索引告诉Python即可。要访问列表元素,可指出列表的名称,再指出元素的索引,并将其放在方括号内。

在Python中,**==第一个列表元素的索引为0,而不是1。==**在大多数编程语言中都是如此,这与列表操作的底层实现相关。

names = ['太上问情', 'test1', 'test2']
print(names[0])

==Python还支持倒序访问,通过设置负数的索引,可以倒数访问列表元素。==

names = ['太上问情', 'test1', 'test2']
# 打印倒数第一个元素
print(names[-1])
# 打印倒数第二个元素
print(names[-2])

6.2 列表元素的增加、删除、修改

修改元素

通过下标索引获取元素对象,然后对对象进行赋值操作,即可修改列表对象。

names = ['太上问情', 'test1', 'test2']
names[0] = 'Taishang'
print(names)

# 结果
['Taishang', 'test1', 'test2']

添加元素

append 在列表末尾添加元素

使用append方法,可以在列表末尾添加元素。

names = ['太上问情', 'test1', 'test2']
# 使用append,从列表末尾添加元素
names.append('test3')
print(names)

# 结果
['太上问情', 'test1', 'test2', 'test3']

insert 从任意位置插入元素

使用insert方法,可以在列表任意合法位置插入元素,插入位置的右侧的元素将整体右移。

names = ['太上问情', 'test1', 'test2']
# 使用insert,从任意位置插入元素,该操作会使列表中既有的每个元素都右移一个位置位置
names.insert(2, 'Taishang')
print(names)

# 结果
['太上问情', 'test1', 'Taishang', 'test2']

删除元素

del 通过索引删除元素

使用del可删除任何位置处的列表元素,条件是知道其索引

names = ['太上问情', 'test1', 'test2']
del names[1]
print(names)

# 结果
['太上问情', 'test2']

pop 获取元素的值并删除元素

方法pop()可删除列表**==末尾==**的元素,并让能够接着使用它。同时也支持通过索引删除任意位置的元素。

# 获取末尾元素并删除
names = ['太上问情', 'test1', 'test2']
print(names.pop())
print(names)

# 结果
test2
['太上问情', 'test1']

# 获取索引为1的元素并删除
names = ['太上问情', 'test1', 'test2']
print(names.pop(1))
print(names)

# 结果
test1
['太上问情', 'test2']

remove 根据值删除元素

==方法remove()只删除第一个指定的值。如果要删除的值可能在列表中出现多次,就需要使用循环来判断是否删除了所有这样的值。==

names = ['太上问情', 'test1', 'test2']
names.remove('太上问情')
print(names)

# 结果
['test1', 'test2']

6.3 列表常用操作

列表排序

sort 对列表本身进行排序

names = ['太上问情', 'test3', 'test2']
# 按字母顺序正向排序
names.sort()
print(names)
# 按字母顺序倒序排序
names.sort(reverse=True)
print(names)

# 结果
['test2', 'test3', '太上问情']
['太上问情', 'test3', 'test2']

sorted 获取排序的新列表,不改变原列表

cars = ['bmw', 'audi', 'toyota', 'subaru']
print("正向排序好的列表:")
print(sorted(cars))
print("倒序排序好的列表:")
print(sorted(cars, reverse=True))
print('原始列表:')
print(cars)

# 结果
正向排序好的列表:
['audi', 'bmw', 'subaru', 'toyota']
倒序排序好的列表:
['toyota', 'subaru', 'bmw', 'audi']
原始列表:
['bmw', 'audi', 'toyota', 'subaru']

倒序列表

cars = ['bmw', 'audi', 'toyota', 'subaru']
cars.reverse()
print(cars)

# 结果
['subaru', 'toyota', 'audi', 'bmw']

len 获取列表长度

cars = ['bmw', 'audi', 'toyota', 'subaru']
print(len(cars))

# 结果
4

遍历列表

Python中可以通过 for item in list 的方式遍历列表,item表示列表中的元素,list表示要遍历的列表。

cars = ['bmw', 'audi', 'toyota', 'subaru']
for car in cars:
    print(car)
    
# 结果
bmw
audi
toyota
subaru

range函数生成范围列表

# 指定最大值
list1 = list(range(4))
# 指定起始范围
list2 = list(range(1, 4))
# 指定起始范围和步长
list3 = list(range(1, 100, 10))
print(list1)
print(list2)
print(list3)

# 结果
[0, 1, 2, 3]
[1, 2, 3]
[1, 11, 21, 31, 41, 51, 61, 71, 81, 91]

使用列表解析

list1 = list(range(1, 11))
squares = [value ** 2 for value in list1]
print(squares)
# 或者
squares = [value ** 2 for value in range(1, 11)]
print(squares)

# 结果
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

列表切片(子集)

cars = list(range(5))
# 指定起始位置切片
print(cars[1:3])
# 不指定开始位置,从列头开始
print(cars[:2])
# 不指定终止位置,从列尾结束
print(cars[2:])
# 不指定起始位置,复制列表
print(cars[:])

# 结果
[1, 2]
[0, 1]
[2, 3, 4]
[0, 1, 2, 3, 4]

5 元组(不可变列表)

列表非常适合用于存储在程序运行期间可能变化的数据集。列表是可以修改的,这对处理网站的用户列表或游戏中的角色列表至关重要。然而,有时候需要创建一系列不可修改的元素,元组可以满足这种需求。==Python将不能修改的值称为不可变的,而不可变的列表被称为元组。==

6.1 定义元组

元组看起来犹如列表,但使用圆括号而不是方括号来标识。定义元组后,就可以使用索引来访问其元素,就像访问列表元素一样。

cars = ('宝马', '奔驰', '大众', '比亚迪', '劳斯莱斯')

6.2 元组元素不可变

cars = ('宝马', '奔驰', '大众', '比亚迪', '劳斯莱斯')
# 演示元组不可变
cars[2] = '小米汽车'

# 结果
Traceback (most recent call last):
  File "F:\python\Study\main.py", line 5, in <module>
    cars[2] = '小米汽车'
TypeError: 'tuple' object does not support item assignment

6.3 存储元组的变量可重新赋值

cars = ('宝马', '奔驰', '大众', '比亚迪', '劳斯莱斯')
print(cars)
cars = ('宝马', '奔驰', '大众', '比亚迪', '劳斯莱斯', '小米汽车')
print(cars)

# 结果
('宝马', '奔驰', '大众', '比亚迪', '劳斯莱斯')
('宝马', '奔驰', '大众', '比亚迪', '劳斯莱斯', '小米汽车')

6 字典(Map)

在Python中,字典是一系列**==键—值对==**。每个键都与一个值相关联,可以使用键来访问与之相关联的值。与键相关联的值可以是数字、字符串、列表乃至字典。事实上,可将任何Python对象用作字典中的值。

键—值对是两个相关联的值。指定键时,Python将返回与之相关联的值。键和值之间用冒号分隔,而键—值对之间用逗号分隔。

6.1 创建字典

# 创建空字典
person = {}
# 创建并初始化字典
person = {
    'name': '太上问情',
    'age': '27',
    'sex': '男人'
}

6.2 操作字典

访问字典

person = {
    'name': '太上问情',
    'age': '27',
    'sex': '男人'
}
print(person['name'])

# 结果
太上问情

添加键

person = {
    'name': '太上问情',
    'age': '27',
    'sex': '男人'
}
# 添加key
person['alias'] = 'Taishang'
print(person)

# 结果
{'name': '太上问情', 'age': '27', 'sex': '男人', 'alias': 'Taishang'}

修改字典的值

person = {
    'name': '太上问情',
    'age': '27',
    'sex': '男人'
}
# 修改字典中的值
person['age'] = 1997
print(person)

# 结果
{'name': '太上问情', 'age': 1997, 'sex': '男人'}

删除字典中的建

和列表一样,字典中也可以使用del语句删除key。

person = {
    'name': '太上问情',
    'age': '27',
    'sex': '男人'
}
# 删除key
del person['age']
print(person)

# 结果
{'name': '太上问情', 'sex': '男人'}

遍历字典

1. 遍历字典的键(Keys)

使用 for 循环直接遍历字典,默认遍历的是字典的键。

Codemy_dict = {'a': 1, 'b': 2, 'c': 3}

# 遍历字典的键
for key in my_dict:
    print(key)

输出:

a
b
c

可以使用 my_dict.keys() 显式地获取字典的键:

Codefor key in my_dict.keys():
    print(key)

这两种方式是等效的,都会遍历字典的所有键。

2. 遍历字典的值(Values)

如果只关心字典中的值,可以使用 my_dict.values() 获取所有值并遍历。

Code# 遍历字典的值
for value in my_dict.values():
    print(value)

输出:

1
2
3

6. 遍历字典的键值对(Key-Value pairs)

使用 my_dict.items() 可以遍历字典中的键值对,返回的是一个 (key, value) 元组。

Code# 遍历字典的键值对
for key, value in my_dict.items():
    print(f"键: {key}, 值: {value}")

输出:

键: a, 值: 1
键: b, 值: 2
键: c, 值: 3

7 if语句-循环

7.1 if语句

if语句是python中的分支结构,和其他语言几乎没有任何区别。

age = 18
if age < 18:
    print("未成年不允许上网吧")

if age >= 18:
    print("您已经成年,欢迎常驻本网吧~")
else:
    print("未成年滚蛋,来了老子要进去!")

if age < 18:
    print("未成年滚蛋,来了老子要进去!")
elif age > 75:
    print("老年人滚蛋,来了老子担惊受怕!")
else:
    print("您正值当年,欢迎常驻本网吧~")

7.2 循环

Python中的循环有for循环和while循环。for循环通常用来遍历列表、元组、字典等,while循环则通常是通过设置退出条件来使用。

for循环

numbers = list(range(10))
for val in numbers:
    print(val)

while循环

age = 0
while age < 18:
    print("未成年")
    age += 1

break 结束循环

age = 0
while True:
    if age >= 18:
        # 使用break结束循环
        break
    else:
        age += 1

continue 跳出本次循环

age = 0
while age < 22:
    age += 1
    if age == 18:
        # 使用continue跳出循环不执行下面的代码
        continue
    print('8折优惠券')

8 函数

Python 中的函数是组织好的、可重用的代码块,用于实现特定的功能。理解 Python 函数的各个关键点对于写出高效、可维护的代码至关重要。以下是 Python 函数的各个关键点,逐步描述:

8.1 定义函数

在 Python 中,函数使用 def 关键字来定义,后跟函数名、圆括号 ( ) 和冒号 :。函数体缩进在冒号后面。

def function_name(parameters):
    # Function body
    pass

示例:

def greet(name):
    print(f"Hello, {name}!")

8.2 函数名

函数名遵循 Python 标识符规则:

  • 只能包含字母、数字和下划线(不能以数字开头)。
  • 函数名应具有描述性,清晰表达该函数的功能。

8.3 参数和参数列表

函数可以接受零个或多个参数。参数列在圆括号中,用逗号分隔。参数可以是任何数据类型(数字、字符串、列表、字典、函数等)。

示例:

def add(x, y):
    return x + y
  • 位置参数:按顺序传递给函数。

  • 默认参数:如果调用时没有传递参数,可以设置默认值。

    def greet(name="Guest"):
        print(f"Hello, {name}!")
    
  • 可变参数:通过 *args 可以传递任意数量的位置参数,**kwargs 用于接受任意数量的关键字参数。

    def example(*args, **kwargs):
        for arg in args:
            print(arg)
        for key, value in kwargs.items():
            print(f"{key}: {value}")
            
    

8.4 函数体

函数体是实际执行的代码块。它是被定义函数的执行主体,位于 def 语句下,缩进四个空格。

示例:

def square(x):
    return x * x

8.5 返回值 (return)

Python 函数通过 return 关键字返回结果。return 语句结束函数的执行,并将后面的值作为结果返回给调用方。

  • 如果没有 return 语句,默认返回 None
  • 一个函数可以有多个 return 语句,但一旦执行了 return,函数立即终止,不会继续执行后面的代码。

示例:

def add(x, y):
    return x + y

result = add(3, 4)  # result 现在是 7

8.6 函数的作用域

函数中定义的变量通常是局部变量,只有在该函数内可见。函数外部无法直接访问函数内部的局部变量。

  • 局部变量:函数内定义的变量,只在函数内有效。
  • 全局变量:在函数外定义的变量,可以在函数内部访问(前提是没有局部同名变量覆盖)。

示例:

x = 10  # 全局变量

def func():
    y = 5  # 局部变量
    print(x, y)

func()  # 输出 10 5

8.7 递归函数

递归函数是指函数在其内部调用自身。递归函数通常需要一个基本条件来终止递归,以防止无限循环。

示例:

def factorial(n):
    if n == 1:  # 基本条件
        return 1
    else:
        return n * factorial(n - 1)

8.8 匿名函数 (Lambda 函数)

Python 支持匿名函数(也叫 Lambda 函数),这种函数通常只用于简短的操作。Lambda 函数由 lambda 关键字定义,可以有任意数量的参数,但只能包含一个表达式。

square = lambda x: x * x
print(square(5))  # 输出 25

8.9 高阶函数

高阶函数是指接受函数作为参数或返回函数的函数。Python 中许多内建函数都是高阶函数,如 map()filter()reduce() 等。

示例:

def apply_function(func, value):
    return func(value)

result = apply_function(lambda x: x * x, 5)  # 输出 25

8.10 函数注解 (Function Annotations)

Python 允许为函数的参数和返回值添加注解,用于说明该参数或返回值的类型。注解本身不会影响代码的执行,主要是用于文档和类型检查工具。

def add(x: int, y: int) -> int:
    return x + y

8.11 函数文档字符串 (Docstring)

Python 函数可以通过 """docstring""" 提供函数的描述。它是函数定义的第一行内容,用于说明函数的用途、参数、返回值等信息。

def greet(name: str) -> None:
    """
    Greets the user with their name.
    
    Parameters:
    name (str): The name of the user.
    
    Returns:
    None
    """
    print(f"Hello, {name}!")

可以使用 help() 函数来查看函数的文档字符串:

help(greet)

8.12 总结

Python 的函数特性非常丰富,可以通过 def 关键字定义函数,使用参数传递信息,利用 return 返回值,支持递归、匿名函数和高阶函数等。理解这些基本概念并灵活运用,可以帮助写出更清晰、更高效的代码。

9 模块

模块是 Python 中组织代码的一种方式,它允许将程序分成多个文件,每个文件包含一些功能,这样就可以将代码逻辑分开,提升代码的可读性、复用性和维护性。Python 中的模块是包含 Python 定义和语句的文件。

9.1 什么是模块?

模块是包含 Python 代码的文件,通常具有 .py 扩展名。模块可以定义函数、类和变量,还可以包含可执行的代码。通过将相关的功能组织到模块中,可以使代码更简洁并易于维护。

示例:

假设有一个文件 math_operations.py,它是一个模块,包含一些数学操作:

# math_operations.py

def add(x, y):
    return x + y

def subtract(x, y):
    return x - y

9.2 导入模块

要使用模块中的功能,可以使用 import 语句导入模块。Python 提供了多种导入模块的方式:

导入整个模块

import math_operations

result = math_operations.add(5, 3)  # 调用模块中的函数
print(result)  # 输出 8

导入模块的特定函数

from math_operations import add

result = add(5, 3)  # 直接调用导入的函数
print(result)  # 输出 8

给模块或函数起别名

可以使用 as 关键字为模块或函数起一个简短的别名。

import math_operations as mo

result = mo.add(5, 3)
print(result)  # 输出 8
from math_operations import add as sum_func

result = sum_func(5, 3)
print(result)  # 输出 8

导入所有模块中的内容

虽然不推荐,但可以用 from module import * 导入模块中的所有内容。

from math_operations import *

result = add(5, 3)
print(result)  # 输出 8

注意:使用 import * 可能会引起命名冲突,尤其是当多个模块中有相同函数名时,因此不推荐这种方式。

9.3 模块的搜索路径

Python 会在一系列路径中查找导入的模块,主要的路径包括:

  • 当前目录
  • Python 标准库路径
  • 环境变量 PYTHONPATH 中的路径

可以通过 sys.path 查看当前 Python 的模块搜索路径:

import sys
print(sys.path)

如果的模块文件不在这些路径中,可以通过 sys.path.append() 添加新的路径。

import sys
sys.path.append('/path/to/your/modules')

9.4 自定义模块

可以创建自己的模块,只需要将 Python 代码保存为 .py 文件,然后在其他文件中导入即可。

例如,创建一个 utils.py 模块:

# utils.py

def greet(name):
    print(f"Hello, {name}!")

然后在另一个 Python 文件中使用它:

# main.py
import utils

utils.greet("Alice")  # 输出 Hello, Alice!

9.5 模块中的特殊变量 __name__

每个模块都有一个内置变量 __name__。当模块作为脚本执行时,__name__ 的值为 "__main__";当模块被导入时,__name__ 的值为模块的名称。

这个特性允许在模块中写一些只在模块作为脚本执行时才会运行的代码,而在作为模块导入时不执行这些代码。

# test.py
def greet(name):
    print(f"Hello, {name}!")

if __name__ == "__main__":
    greet("Alice")  # 只会在直接运行此脚本时执行

当直接运行 test.py 时,__name__ 的值是 "__main__"greet("Alice") 会执行;而当它作为模块被导入时,这部分代码不会被执行。

# 导入 test 模块
import test  # 不会执行 greet("Alice")

9.6 标准库模块

Python 提供了许多标准库模块,涵盖了文件操作、数据结构、网络通信、正则表达式等多个方面。可以直接导入并使用它们。

例如:

  • math:提供数学函数,如平方根、对数等。
  • datetime:提供日期和时间处理功能。
  • os:提供与操作系统交互的功能。
  • random:生成随机数。
  • json:处理 JSON 数据。

示例:

import math
print(math.sqrt(16))  # 输出 4.0

import datetime
print(datetime.datetime.now())  # 输出当前日期和时间

9.7 第三方模块

除了 Python 标准库,Python 还支持安装第三方模块,通常通过 pip 工具来安装。常见的第三方模块有:

  • requests:用于发送 HTTP 请求。
  • numpy:用于科学计算,提供多维数组和矩阵运算。
  • pandas:用于数据分析,提供数据处理工具。
  • flask:用于开发 Web 应用。

安装第三方模块:

pip install requests

安装完成后,就可以像使用标准库模块一样导入并使用这些模块:

import requests

response = requests.get("https://www.example.com")
print(response.text)

9.8 包(Package)

包是一个包含多个模块的目录。包目录下必须包含一个 __init__.py 文件(即使它是空的),以标识该目录是一个 Python 包。

假设有一个目录结构如下:

my_package/
    __init__.py
    module1.py
    module2.py

可以导入包中的模块:

from my_package import module1
from my_package.module2 import some_function

包可以进一步组织成子包,形成层次化的结构。

9.9 总结

模块是 Python 中组织代码的基础单元,通过模块,可以将相关功能组合在一起,并通过 import 语句在其他地方重用它们。模块使得代码更清晰、可维护且易于共享。在开发大型项目时,模块和包的使用尤其重要,有助于提升代码的结构性和可扩展性。

10 类(Class)

面向对象编程(OOP)中,类(Class)是自定义的数据类型,用来描述一类事物的特征和行为。类是对象的模板或蓝图,通过类定义的属性和方法,创建对象并对其进行操作。

10.1 定义类

使用 class 关键字来定义类。类通常由类名、构造方法、属性和方法组成。

示例:定义一个简单的类 Person

class Person:
    def __init__(self, name, age):
        self.name = name  # 属性:姓名
        self.age = age    # 属性:年龄

    def introduce(self):
        print(f"Hello, my name is {self.name} and I am {self.age} years old.")

10.2 创建对象(实例化类)

定义完类之后,可以通过类来创建对象(实例)。对象是类的具体实现,拥有类定义的属性和方法。

示例:创建对象并调用方法

# 创建一个 Person 对象
person1 = Person("Alice", 30)

# 调用对象的方法
person1.introduce()  # 输出:Hello, my name is Alice and I am 30 years old.

10.3 类的构造方法 __init__

__init__ 是类的初始化方法,在创建对象时自动调用,用于初始化对象的属性。self 参数指向当前实例。

示例:定义类的构造方法

class Car:
    def __init__(self, make, model, year):
        self.make = make  # 品牌
        self.model = model  # 型号
        self.year = year  # 年份

    def start(self):
        print(f"The {self.make} {self.model} is starting.")

# 创建 Car 对象
car1 = Car("Toyota", "Corolla", 2020)
car1.start()  # 输出:The Toyota Corolla is starting.

10.4 类的属性和方法

10.4.1 属性(成员变量)

类中的属性是通过 self 关键字定义的,用来描述对象的特征。

示例:定义实例属性

class Dog:
    def __init__(self, name, breed):
        self.name = name  # 实例属性:姓名
        self.breed = breed  # 实例属性:品种

dog = Dog("Buddy", "Golden Retriever")
print(dog.name)  # 输出:Buddy
print(dog.breed)  # 输出:Golden Retriever

10.4.2 方法(成员函数)

方法是类中定义的函数,描述对象的行为或操作。

示例:定义方法并调用

class Calculator:
    def add(self, a, b):
        return a + b

    def subtract(self, a, b):
        return a - b

calc = Calculator()
print(calc.add(5, 3))  # 输出:8
print(calc.subtract(5, 3))  # 输出:2

10.5 类的继承

继承是 OOP 中的一个重要特性,子类可以继承父类的属性和方法。继承使得子类可以复用父类的代码,并可以对父类的方法进行扩展或重写。

示例:继承父类 AnimalDog

class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        print("Animal makes a sound.")

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)  # 调用父类构造方法
        self.breed = breed

    def speak(self):  # 重写父类方法
        print(f"{self.name} barks.")

dog = Dog("Buddy", "Golden Retriever")
dog.speak()  # 输出:Buddy barks.

10.6 类的封装

封装是将对象的属性和方法封装在类中,控制外部对对象的访问。通过方法来访问或修改属性,而不是直接访问属性,提高数据安全性和代码的可维护性。

10.6.1 公有属性和私有属性

Python 中的属性默认为公有(public),可以被外部访问。如果需要私有属性,可以通过在属性名前加双下划线 __ 来实现。

示例:公有和私有属性

class Person:
    def __init__(self, name, age):
        self.name = name
        self.__age = age  # 私有属性

    def get_age(self):
        return self.__age

    def set_age(self, age):
        if age > 0:
            self.__age = age
        else:
            print("Invalid age.")

# 创建对象
person = Person("Alice", 30)
print(person.name)  # 公有属性,可以直接访问
print(person.get_age())  # 通过方法访问私有属性
person.set_age(35)  # 设置新年龄
print(person.get_age())  # 输出 35

10.6.2 访问控制

Python 中没有强制的访问修饰符,但可以通过双下划线来实现私有属性。这并不意味着属性完全无法访问,而是通过名称重整使其更难以直接访问。

10.7 类的多态

多态是指不同类的对象可以通过相同的方法调用展现不同的行为。多态通常依赖于继承和方法重写。

示例:动物的多态表现

class Animal:
    def speak(self):
        print("Animal makes a sound.")

class Dog(Animal):
    def speak(self):
        print("Dog barks.")

class Cat(Animal):
    def speak(self):
        print("Cat meows.")

animals = [Dog(), Cat()]
for animal in animals:
    animal.speak()  # 根据不同的对象调用相应的 `speak` 方法

输出:

Dog barks.
Cat meows.

10.8 类的总结

  • 类是对象的模板,包含属性和方法,描述对象的特征和行为。
  • 类通过 __init__ 方法初始化,self 用于访问实例属性。
  • 继承允许子类复用父类的代码,并可以扩展或修改父类的行为。
  • 封装通过控制属性的访问权限来提高安全性。
  • 多态使得不同类的对象通过相同接口展现不同的行为。

通过类和对象,可以组织和管理复杂的程序代码,是 Python 面向对象编程的核心概念。

11 输入输出(I/O)操作

11.1 输入操作:input() 函数

input() 函数用于获取用户输入。它会从用户输入一行数据,并将其返回为字符串类型。

语法:

input([prompt])
  • prompt 是可选的,表示在输入框前显示的提示信息。

示例:

# 获取用户输入并打印
name = input("请输入您的名字: ")
print(f"你好, {name}!")

说明

  • input() 函数会读取一行输入并返回字符串类型,如果输入的是数字或其他类型的数据,返回的仍然是字符串。

如果要输入数字类型,可以将返回的字符串转换为 intfloat

# 获取整数输入
age = int(input("请输入您的年龄: "))
print(f"您的年龄是 {age} 岁")

# 获取浮点数输入
height = float(input("请输入您的身高(米): "))
print(f"您的身高是 {height} 米")

11.2 输出操作:print() 函数

print() 用于将信息输出到控制台(标准输出)。可以打印字符串、变量或表达式的结果。

语法:

print(*objects, sep=' ', end='\n', file=sys.stdout)
  • objects:一个或多个要输出的对象。
  • sep:指定输出多个对象时的分隔符,默认为空格。
  • end:指定输出的结尾符,默认为换行符 \n
  • file:指定输出流,默认为标准输出。

示例:

# 输出字符串
print("Hello, World!")

# 输出多个变量
name = "Alice"
age = 25
print(name, age)  # 默认用空格分隔,输出: Alice 25

# 格式化输出
print(f"我的名字是 {name},年龄是 {age} 岁")  # 使用 f-string 格式化输出

# 修改输出结尾字符
print("Hello", end=" ")
print("World!")  # 输出: Hello World!

# 指定分隔符
print("apple", "banana", "cherry", sep=", ")  # 输出: apple, banana, cherry

11.3 标准输入输出的重定向:sys 模块

sys 模块提供了对标准输入输出流的访问,可以通过它进行输入输出的重定向。

示例:

import sys

# 将输出重定向到文件
sys.stdout = open('output.txt', 'w')
print("这条信息会被写入到 output.txt 文件")

# 还原输出到终端
sys.stdout = sys.__stdout__

# 将输入重定向到文件
sys.stdin = open('input.txt', 'r')
user_input = input()  # 从 input.txt 中读取输入
print(user_input)

12 文件操作

文件操作是 Python 中常见的任务之一,Python 提供了非常简洁的 API 来进行文件的读写和处理。

12.1 打开文件:open() 函数

open() 函数用于打开文件,返回一个文件对象。你可以通过该文件对象执行读写操作。

语法:

open(filename, mode)
  • filename:文件名或文件路径。
  • mode:文件打开模式,指定文件的操作方式(如读取、写入、追加等)。

常见的文件打开模式:

  • 'r':读取模式(默认模式),文件必须存在。
  • 'w':写入模式,如果文件存在则覆盖,不存在则创建。
  • 'a':追加模式,向文件末尾添加内容。
  • 'b':二进制模式(用于图片、音频等文件的读写)。
  • 'rb''wb':二进制文件读取/写入模式。
  • 'r+':读写模式,文件必须存在。

示例:

# 打开文件进行读取
file = open('example.txt', 'r')
content = file.read()  # 读取整个文件内容
print(content)
file.close()  # 手动关闭文件

# 使用 with 语句自动关闭文件
with open('example.txt', 'r') as file:
    content = file.read()
    print(content)  # 自动关闭文件

11.2 文件读取方法

  • read(size):读取文件的指定字节数。如果没有指定 size,则读取整个文件。
  • readline():读取文件的一行。
  • readlines():读取文件的所有行,并返回一个列表。

示例:

# 逐行读取文件
with open('example.txt', 'r') as file:
    for line in file:
        print(line.strip())  # strip() 去掉每行末尾的换行符

# 使用 readlines() 读取所有行
with open('example.txt', 'r') as file:
    lines = file.readlines()
    print(lines)  # 输出文件中的所有行,作为一个列表

11.3 文件写入方法

  • write(string):将指定的字符串写入文件。
  • writelines(lines):将一个列表或可迭代对象中的每个元素写入文件。

示例:

# 写入文本到文件
with open('output.txt', 'w') as file:
    file.write("Hello, world!\n")
    file.write("This is a test file.\n")

# 追加内容到文件
with open('output.txt', 'a') as file:
    file.write("This is an appended line.\n")

# 使用 writelines() 写入多行
lines = ["Line 1\n", "Line 2\n", "Line 3\n"]
with open('output.txt', 'w') as file:
    file.writelines(lines)

13 异常处理

异常处理允许程序在出现错误时保持运行,而不是直接崩溃。Python 提供了 tryexceptelsefinally 语句来处理异常。

13.1 基本异常处理

使用 try 来包裹可能出现错误的代码,使用 except 捕获并处理异常。

示例:

try:
    # 可能发生错误的代码
    result = 10 / 0
except ZeroDivisionError:
    print("除数不能为零!")

13.2 捕获多个异常

可以通过多个 except 块来捕获不同类型的异常,或者使用一个 except 来捕获所有异常。

示例:

try:
    num = int(input("请输入一个数字: "))
    result = 10 / num
except ZeroDivisionError:
    print("除数不能为零!")
except ValueError:
    print("请输入有效的数字!")
except Exception as e:
    print(f"发生了一个未知错误: {e}")

13.3 使用 elsefinally

  • else:没有异常时执行的代码。
  • finally:无论是否发生异常,都会执行的代码块,通常用于资源释放等操作。

示例:

try:
    result = 10 / 5
except ZeroDivisionError:
    print("除以零错误!")
else:
    print(f"结果是: {result}")
finally:
    print("这部分代码无论如何都会执行")

13.4 自定义异常

你可以创建自己的异常类,继承自 Exception 基类,以便在特定情况下抛出自定义的错误。

示例:

class CustomError(Exception):
    def __init__(self, message):
        super().__init__(message)

try:
    raise CustomError("这是一个自定义异常")
except CustomError as e:
    print(f"捕获到自定义异常: {e}")

14 Lambda 表达式

lambda 表达式是 Python 中用于创建匿名函数(即没有名字的函数)的一种简洁方式。它通常用于需要快速定义一个小函数的场景,尤其是作为参数传递给其他函数时。

14.1 基本语法

lambda 参数: 表达式
  • lambda 关键字表示创建一个匿名函数。
  • 参数 是函数的输入,可以是多个参数,用逗号分隔。
  • 表达式 是匿名函数的主体部分,通常是一个单一的表达式,不能包含语句。

14.2 示例

1. 最简单的 lambda 表达式

一个简单的 lambda 表达式,接收两个参数,返回它们的和:

# 使用 lambda 表达式定义一个加法函数
add = lambda x, y: x + y
print(add(3, 5))  # 输出: 8

2. 没有参数的 lambda 表达式

lambda 表达式也可以没有参数,返回一个常数:

# 定义一个无参数的 lambda 表达式,返回常数 42
get_answer = lambda: 42
print(get_answer())  # 输出: 42

3. 用于函数式编程

lambda 表达式常与内置的高阶函数(如 map()filter()sorted() 等)一起使用。

示例 1: 使用 map()lambda

将列表中的每个数字乘以 2:

numbers = [1, 2, 3, 4]
doubled_numbers = map(lambda x: x * 2, numbers)
print(list(doubled_numbers))  # 输出: [2, 4, 6, 8]

示例 2: 使用 filter()lambda

过滤出列表中所有的偶数:

numbers = [1, 2, 3, 4, 5, 6]
even_numbers = filter(lambda x: x % 2 == 0, numbers)
print(list(even_numbers))  # 输出: [2, 4, 6]

示例 3: 使用 sorted()lambda

按字符串的长度对列表进行排序:

words = ["apple", "banana", "cherry", "date"]
sorted_words = sorted(words, key=lambda x: len(x))
print(sorted_words)  # 输出: ['date', 'apple', 'cherry', 'banana']

4. 在 sorted() 中指定排序规则

# 按字母顺序对元组列表排序
tuples = [('a', 3), ('b', 1), ('c', 2)]
sorted_tuples = sorted(tuples, key=lambda x: x[1])  # 按元组中的第二个元素排序
print(sorted_tuples)  # 输出: [('b', 1), ('c', 2), ('a', 3)]

14.3 为什么使用 lambda 表达式

  1. 简洁性:对于只需要一行代码的函数,lambda 表达式通常比 def 更简洁。
  2. 匿名性lambda 函数没有名字,可以在函数需要的地方使用,不必为每个简单的操作都定义一个完整的函数。
  3. 更适合传递给高阶函数:如 map()filter()sorted() 等,lambda 可以在这些函数的参数中直接定义。

14.4 lambda 与普通函数的对比

  • lambda 表达式创建的是匿名函数,通常用于临时的小操作。
  • def 语句用于定义普通函数,可以包含多行代码。

示例对比:

1. 使用 lambda

add = lambda x, y: x + y
print(add(3, 5))  # 输出: 8

2. 使用 def

def add(x, y):
    return x + y

print(add(3, 5))  # 输出: 8

14.5 注意事项

  • lambda 表达式只能包含一个表达式,不能有语句(如 if 语句、循环等)。如果需要多个操作,应该使用常规的 def 函数。
  • lambda 常用于那些只需要简单操作的场景,例如传递给其他函数(如 map()filter()sorted() 等)。
0

评论区