Skip to content

Python 3 教程(runoob)

AI 编程助手 (Fitten Code)

  • Python AI 编程助手:
    • Fitten Code 免费且支持 80 多种语言:Python、C++、Javascript、Typescript、Java 等。 Agent 自主编程智能体 自主编程智能体具备强大的主动执行能力:
  • 根据任务需求智能调用工具,主动分析背景信息;
  • 自主拆解复杂问题,通过多步骤迭代精准完成任务;
  • 显著提升编程自动化效率与精细度。

基础语法

编码:Python 3 源代码文件默认使用 UTF-8 编码,所有字符串都是 unicode 字符串。 当然你也可以为源码文件指定不同的编码:

python
# -*- coding: cp-1252 -*-

标识符

  • 标识符(identifier):变量名、函数名、类名等。
py
# 合法标识符示例
age = 25                        # 普通变量名,最常见
user_name = "Alice"             # 用下划线连接单词,清晰易读
_total = 100                    # 下划线开头通常表示“内部使用”或“私有”
MAX_SIZE = 1024                 # 全大写通常表示“常量”(固定不变的值)
calculate_area()                # 函数名,动词+名词
StudentInfo                     # 类名,首字母大写(驼峰命名法)
__private_var                   # 双下划线开头,有特殊含义
# 非法标识符示例
2nd_place = "silver"            # 错误:以数字开头
user-name = "Bob"               # 错误:包含连字符
class = "Math"                  # 错误:使用关键字
$price = 9.99                   # 错误:包含特殊字符
for = "loop"                    # 错误:使用关键字
@special_var = "value"          # 错误:包含特殊字符
# 以下标识符也是非法的
True = "false"                  # 错误:使用关键字
False = "true"                  # 错误:使用关键字
None = "value"                  # 错误:使用关键字
# Python 3 允许使用 Unicode 字符作为标识符,可以用中文作为变量名,非 ASCII 标识符也是允许的了。
姓名 = "张三"                    # 合法
π = 3.14159                     # 合法

注释

Python中单行注释以 # 开头,注释内容会被解释器忽略。 多行注释可以用多个 # 号,还有 ''' 和 """

#!/usr/bin/python3

  1. #!:这是Shebang的标志,用于告诉操作系统脚本应该使用哪个解释器来运行。它是一个特殊的注释,> 只有在脚本作为可执行文件直接运行时才会被识别。

  2. /usr/bin/python3:这是指定的解释器路径。在类Unix操作系统(如Linux、macOS)中,这个路径> 通常指向Python 3的解释器。这意味着当脚本被直接执行时,系统会使用位于/usr/bin/python3路径下> 的Python解释器来运行这个脚本。

多行语句

Python 通常是一行写完一条语句,但如果语句很长,我们可以使用反斜杠 \ 来实现多行语句,

py
total = item_one + \
        item_two + \
        item_three

数字(Number)类型

python中数字有四种类型:整数、布尔型、浮点数和复数。

  1. int (整数), 如 1, 只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。
  2. bool (布尔), 如 True。
  3. float (浮点数), 如 1.23、3E-2
  4. complex (复数) - 复数由实部和虚部组成,形式为 a + bj,其中 a 是实部,b 是虚部,j 表示虚数单位。如 1 + 2j、 1.1 + 2.2j

字符串

  1. Python 中单引号 ' 和双引号 " 使用完全相同。
  2. 使用三引号(''' 或 """)可以指定一个多行字符串。
  3. 转义符 \。
  4. 反斜杠可以用来转义,使用 r 可以让反斜杠不发生转义。 如 r"this is a line with \n" 则 \n 会显示,并不是换行。
  5. 按字面意义级联字符串,如 "this " "is " "string" 会被自动转换为 this is string。
  6. 字符串可以用 + 运算符连接在一起,用 * 运算符重复。
  7. Python 中的字符串有两种索引方式,从左往右以 0 开始,从右往左以 -1 开始。
  8. Python 中的字符串不能改变。
  9. Python 没有单独的字符类型,一个字符就是长度为 1 的字符串。
  10. 字符串切片 str[start:end],其中 start(包含)是切片开始的索引,end(不包含)是切片结束的索引。
  11. 字符串的切片可以加上步长参数 step,语法格式如下:str[start🔚step]
    1. 步长参数 step 表示每次取字符的间隔,默认值为 1。
    2. 如果 step 为负数,则表示从右往左取字符。
    3. 切片操作返回的是一个新的字符串,不会改变原字符串。

同一行显示多条语句

Python 可以在同一行中使用多条语句,语句之间使用分号 ; 隔开。

py
a = 1; b = 2; c = a + b; print(c);

多个语句构成代码组

缩进相同的一组语句构成一个代码块,我们称之代码组。 像if、while、def和class这样的复合语句,首行以关键字开始,以冒号( : )结束,该行之后的一行或多行代码构成代码组。 我们将首行及后面的代码组称为一个子句(clause)。 如下实例:

py
if expression : 
   suite
elif expression : 
   suite 
else : 
   suite

print 默认输出是换行的,如果要实现不换行需要在变量末尾加上 end="":

py
print("Hello World!")
print("Hello World!", end="")

import 与 from...import

在 python 用 import 或者 from...import 来导入相应的模块。

将整个模块(somemodule)导入,格式为: import somemodule 从某个模块中导入某个函数,格式为: from somemodule import somefunction 从某个模块中导入多个函数,格式为: from somemodule import firstfunc, secondfunc, thirdfunc 将某个模块中的全部函数导入,格式为: from somemodule import *

注意:

  1. 导入模块时,模块名要写在 import 或 from...import 后面,不能写在前面。
  2. 导入模块时,模块名不能包含特殊字符,如 -、.、空格等。

Python3 基本数据类型

Python 中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。 在 Python 中,变量就是变量,它没有类型,我们所说的"类型"是变量所指的内存中对象的类型。 等号(=)用来给变量赋值。 等号(=)运算符左边是一个变量名,等号(=)运算符右边是存储在变量中的值。

多个变量赋值

Python允许你同时为多个变量赋值。例如:

py
a = b = c = 1 # 创建一个整型对象,值为 1,从后向前赋值,三个变量被赋予相同的数值。
a, b, c = 1, 2, "runoob"  # 两个整型对象 1 和 2 的分配给变量 a 和 b,字符串对象 "runoob" 分配给变量 c。

标准数据类型

Python3 中常见的数据类型有:

  • Number(数字)
  • String(字符串)
  • bool(布尔类型)
  • List(列表)
  • Tuple(元组)
  • Set(集合)
  • Dictionary(字典)

Python3 的六个标准数据类型中

  • 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
  • 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。 此外还有一些高级的数据类型,如: 字节数组类型(bytes)。

Number(数字)

Python3 支持 intfloatboolcomplex(复数) 内置的 type() 函数可以用来查询变量所指的对象类型。 此外还可以用 isinstance 来判断:

python
    a, b, c, d = 20, 5.5, True, 4+3j
    print(type(a), type(b), type(c), type(d))
    a = 111
    isinstance(a, int)

isinstance 和 type 的区别在于

  • type()不会认为子类是一种父类类型。
  • isinstance()会认为子类是一种父类类型

注意:Python3 中,boolint 的子类,True 和 False 可以和数字相加, True==1、False==0 会返回 True,但可以通过 is 来判断类型。

del语句

使用del语句删除一些对象引用。

del 语句的语法是: del var1[, var2[, var3[...., varN]]] 您可以通过使用 del 语句删除单个或多个对象。例如: del var del var_a, var_b

注意:

1、Python可以同时为多个变量赋值,如a, b = 1, 2。 2、一个变量可以通过赋值指向不同类型的对象。 3、数值的除法包含两个运算符:/ 返回一个浮点数// 返回一个整数。 4、在混合计算时,Python会把整型转换成为浮点数

String(字符串)

Python中的字符串用单引号 ' 或双引号 " 括起来,同时使用反斜杠 \ 转义特殊字符。

字符串的截取的语法格式如下: 变量[头下标:尾下标] 索引值以 0 为开始值,-1 为从末尾的开始位置。 Python 使用反斜杠 \ 转义特殊字符,如果你不想让反斜杠发生转义,可以在字符串前面添加一个 r,表示原始字符串:

py
>>> print('Ru\noob')
Ru
oob
>>> print(r'Ru\noob')
Ru\noob
>>>

另外,反斜杠()可以作为续行符,表示下一行是上一行的延续。也可以使用 """...""" 或者 '''...''' 跨越多行 与 C 字符串不同的是,Python 字符串不能被改变。向一个索引位置赋值,比如 word[0] = 'm' 会导致错误。 1、反斜杠可以用来转义,使用r可以让反斜杠不发生转义。 2、字符串可以用+运算符连接在一起,用*运算符重复。 3、Python中的字符串有两种索引方式,从左往右以0开始,从右往左以-1开始。 4、Python中的字符串不能改变。

bool(布尔类型)

布尔类型即 True 或 False。 在 Python 中,True 和 False 都是关键字,表示布尔值。 布尔类型可以用来控制程序的流程,比如判断某个条件是否成立,或者在某个条件满足时执行某段代码。

布尔类型特点

布尔类型只有两个值:True 和 False。 bool 是 int 的子类,因此布尔值可以被看作整数来使用,其中 True 等价于 1。 布尔类型可以和其他数据类型进行比较,比如数字、字符串等。在比较时,Python 会将 True 视为 1,False 视为 0。 布尔类型可以和逻辑运算符一起使用,包括 and、or 和 not。这些运算符可以用来组合多个布尔表达式,生成一个新的布尔值。 布尔类型也可以被转换成其他数据类型,比如整数、浮点数和字符串。在转换时,True 会被转换成 1,False 会被转换成 0。 可以使用 bool() 函数将其他类型的值转换为布尔值。以下值在转换为布尔值时为 False:None、False、零 (0、0.0、0j)、空序列(如 ''、()、[])和空映射(如 {})。其他所有值转换为布尔值时均为 True。 注意: 在 Python 中,所有非零的数字和非空的字符串、列表、元组等数据类型都被视为 True,只有 0、空字符串、空列表、空元组等被视为 False。因此,在进行布尔类型转换时,需要注意数据类型的真假性。

List(列表)

List(列表) 是 Python 中使用最频繁的数据类型。 列表可以完成大多数集合类的数据结构实现。列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)。 列表是写在方括号 [] 之间、用逗号分隔开的元素列表。 和字符串一样,列表同样可以被索引和截取,列表被截取后返回一个包含所需元素的新列表。 列表截取的语法格式如下: 变量[头下标:尾下标] 索引值以 0 为开始值,-1 为从末尾的开始位置。 加号 + 是列表连接运算符,星号 * 是重复操作。如下实例: 与Python字符串不一样的是,列表中的元素是可以改变的: List 内置了有很多方法,例如 append()、pop() 等等,这在后面会讲到。

注意

1、列表写在方括号之间,元素用逗号隔开。 2、和字符串一样,列表可以被索引和切片。 3、列表可以使用 + 操作符进行拼接。 4、列表中的元素是可以改变的。

Tuple(元组)

元组(tuple)与列表类似,不同之处在于元组的元素不能修改。元组写在小括号 () 里,元素之间用逗号隔开。 元组中的元素类型也可以不相同: 元组与字符串类似,可以被索引且下标索引从0开始,-1 为从末尾开始的位置。也可以进行截取(看上面,这里不再赘述)。 其实,可以把字符串看作一种特殊的元组。 构造包含 0 个或 1 个元素的元组比较特殊,所以有一些额外的语法规则:

py
tup1 = ()    # 空元组
tup2 = (20,) # 一个元素,需要在元素后添加逗号

注意

1、与字符串一样,元组的元素不能修改。 2、元组也可以被索引和切片,方法一样。 3、注意构造包含 0 或 1 个元素的元组的特殊语法规则。 4、元组也可以使用 + 操作符进行拼接。

Set(集合)

Python 中的集合(Set)是一种无序可变的 数据类型,用于存储唯一的元素。 集合中的元素不会重复,并且可以进行交集、并集、差集等常见的集合操作。 在 Python 中,集合使用大括号 {} 表示,元素之间用逗号 , 分隔。 另外,也可以使用 set() 函数创建集合。 注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。创建格式:

py
parame = {value01,value02,...}
或者
set(value)

#!/usr/bin/python3
sites = {'Google', 'Taobao', 'Runoob', 'Facebook', 'Zhihu', 'Baidu'}
print(sites)   # 输出集合,重复的元素被自动去掉
# 成员测试
if 'Runoob' in sites :
    print('Runoob 在集合中')
else :
    print('Runoob 不在集合中')
# set可以进行集合运算
a = set('abracadabra')
b = set('alacazam')
print(a)
print(a - b)     # a 和 b 的差集
print(a | b)     # a 和 b 的并集
print(a & b)     # a 和 b 的交集
print(a ^ b)     # a 和 b 中不同时存在的元素

Dictionary(字典)

字典(dictionary)是Python中另一个非常有用的内置数据类型。 列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。 字典是一种映射类型,字典用 { } 标识,它是一个无序的 键(key) : 值(value) 的集合。 键(key)必须使用不可变类型。 在同一个字典中,键(key)必须是唯一的。 构造函数 dict() 可以直接从键值对序列中构建字典如下:

py
dict([('Runoob', 1), ('Google', 2), ('Taobao', 3)]) # {'Runoob': 1, 'Google': 2, 'Taobao': 3}
{x: x**2 for x in (2, 4, 6)}     #该代码使用的是字典推导式 # {2: 4, 4: 16, 6: 36}
 dict(Runoob=1, Google=2, Taobao=3)                 # {'Runoob': 1, 'Google': 2, 'Taobao': 3}

注意

1、字典是一种映射类型,它的元素是键值对。 2、字典的关键字必须为不可变类型,且不能重复。 3、创建空字典使用

bytes 类型

在 Python3 中,bytes 类型表示的是不可变的二进制序列(byte sequence)。 与字符串类型不同的是,bytes 类型中的元素是整数值(0 到 255 之间的整数),而不是 Unicode 字符。 bytes 类型通常用于处理二进制数据,比如图像文件、音频文件、视频文件等等。在网络编程中,也经常使用 bytes 类型来传输二进制数据。 创建 bytes 对象的方式有多种,最常见的方式是使用 b 前缀: 此外,也可以使用 bytes() 函数将其他类型的对象转换为 bytes 类型。bytes() 函数的第一个参数是要转换的对象,第二个参数是编码方式,如果省略第二个参数,则默认使用 UTF-8 编码:

py
x = bytes("hello", encoding="utf-8")

与字符串类型类似,bytes 类型也支持许多操作和方法,如切片、拼接、查找、替换等等。同时,由于 bytes 类型是不可变的,因此在进行修改操作时需要创建一个新的 bytes 对象。 例如,要将一个 bytes 对象中的某个字节替换为另一个字节,可以使用切片操作和拼接操作:

py
x = b"hello"
y = x[:2] + b"p" + x[3:]
print(y) # b"heplo"

Python3 数据类型转换

Python3 中,数据类型转换分为两种:

  • 隐式类型转换 - 自动完成
  • 显式类型转换 - 需要使用类型函数来转换 ( int()、float()、str() )

数据类型的转换,一般情况下你只需要将数据类型作为函数名即可 在 Python3 中,数据类型转换可以使用内置函数进行。 以下是一些常用的数据类型转换函数:

int(x):将 x 转换为整数类型。 float(x):将 x 转换为浮点数类型。 str(x):将 x 转换为字符串类型。 list(x):将 x 转换为列表类型。 tuple(x):将 x 转换为元组类型。 set(x):将 x 转换为集合类型。 dict(x):将 x 转换为字典类型。

Python3 运算符

算术运算符

运算符描述实例
+加 - 两个对象相加 a + b 输出结果 31
-减 - 得到负数或是一个数减去另一个数 a - b 输出结果 -11
*乘 - 两个数相乘或是返回一个被重复若干次的字符串 a * b 输出结果 210
/除 - x 除以 y b / a 输出结果 2.1
%取模 - 返回除法的余数 b % a 输出结果 1
**幂 - 返回x的y次幂 a**b 为10的21次方
//取整除 - 往小的方向取整数
>>> 9//2
4
>>> -9//2
-5
## Python 比较运算符
运算符描述实例
==等于 - 比较对象是否相等 (a == b) 返回 False。
!=不等于 - 比较两个对象是否不相等 (a != b) 返回 True。
<小于 - 返回x是否小于y (a < b) 返回 True。
<=小于等于 - 返回x是否小于等于y (a <= b) 返回 True。
>大于 - 返回x是否大于y (a > b) 返回 False。
>=大于等于 - 返回x是否大于等于y (a >= b) 返回 False。
## Python 赋值运算符
运算符描述实例
=简单的赋值运算符 c = a + b 将 a + b 的结果赋值为 c
+=加法赋值运算符 c += a 等效于 c = c + a
-=减法赋值运算符 c -= a 等效于 c = c - a
*=乘法赋值运算符 c *= a 等效于 c = c * a
/=除法赋值运算符 c /= a 等效于 c = c / a
%=取模赋值运算符 c %= a 等效于 c = c % a
**=幂赋值运算符 c **= a 等效于 c = c ** a
//=取整除赋值运算符 c //= a 等效于 c = c // a
:=海象运算符 在这个示例中,赋值表达式可以避免调用 len() 两次: ```py if (n := len(a)) > 10: print(f"List is too long ({n} elements, expected <= 10)") ```

海象运算符

在 Python 3.8 及更高版本中,引入了一种新的语法特性,称为"海象运算符"(Walrus Operator),它使用 := 符号。这个运算符的主要目的是在表达式中同时进行赋值和返回赋值的值。

使用海象运算符可以在一些情况下简化代码,尤其是在需要在表达式中使用赋值结果的情况下。这对于简化循环条件或表达式中的重复计算很有用。

海象运算符的优点

  • 海象运算符(:=)允许在表达式内部进行赋值,这可以减少代码的重复,提高代码的可读性和简洁性。
  • 在上述例子中,传统写法需要单独一行来赋值 n,然后在 if 语句中进行条件检查。而使用海象运算符的写法可以在 if 语句中直接进行赋值和条件检查。

Python位运算符

位运算符是用来对二进制数进行操作的运算符。Python 中的位运算符包括:

  • &(按位与)
  • |(按位或)
  • ^(按位异或)
  • ~(按位取反)
  • <<(左移)
  • >>(右移)

这些运算符可以用于整数类型(int)和布尔类型(bool)。

Python逻辑运算符

逻辑运算符用于组合条件表达式,返回 True 或 False。Python 中的逻辑运算符包括:

  • and(与)
  • or(或)
  • not(非)

这些运算符可以用于布尔类型(bool)的操作数。

Python成员运算符

除了以上的一些运算符之外,Python还支持成员运算符,测试实例中包含了一系列的成员,包括字符串,列表或元组。 成员运算符用于测试序列中是否包含指定的元素。Python 中的成员运算符包括:

运算符描述实例
in 如果在指定的序列中找到值返回 True,否则返回 False。 x 在 y 序列中 , 如果 x 在 y 序列中返回 True。
not in如果在指定的序列中没有找到值返回 True,否则返回 False。x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。

Python身份运算符

身份运算符用于比较两个对象的存储单元

运算符描述实例
is is 是判断两个标识符是不是引用自一个对象x is y, 类似 id(x) == id(y) , 如果引用的是同一个对象则返回 True,否则返回 False
is notis not 是判断两个标识符是不是引用自不同对象 x is not y , 类似 id(x) != id(y)。如果引用的不是同一个对象则返回结果 True,否则返回 False。
### is 与 == 区别: is 用于判断两个变量引用对象是否为同一个, == 用于判断引用变量的值是否相等。

注意: Python3 已不支持 <> 运算符,可以使用 != 代替,如果你一定要使用这种比较运算符,可以使用以下的方式:

end 关键字

关键字end可以用于将结果输出到同一行,或者在输出的末尾添加不同的字符,实例如下: print(b, end=',')

Python 推导式

Python 推导式是一种独特的数据处理方式,可以从一个数据序列构建另一个新的数据序列的结构体。 Python 推导式是一种强大且简洁的语法,适用于生成列表、字典、集合和生成器。 在使用推导式时,需要注意可读性,尽量保持表达式简洁,以免影响代码的可读性和可维护性。

列表推导式

列表推导式格式为:

py
[表达式 for 变量 in 列表] 
[out_exp_res for out_exp in input_list]
# 或者 
[表达式 for 变量 in 列表 if 条件]
[out_exp_res for out_exp in input_list if condition]

names = ['Bob','Tom','alice','Jerry','Wendy','Smith']
new_names = [name.upper()for name in names if len(name)>3]
print(new_names)
['ALICE', 'JERRY', 'WENDY', 'SMITH']

multiples = [i for i in range(30) if i % 3 == 0]
print(multiples)
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
  • out_exp_res:列表生成元素表达式,可以是有返回值的函数。
  • for out_exp in input_list:迭代 input_list 将 out_exp 传入到 out_exp_res 表达式中。
  • if condition:条件语句,可以过滤列表中不符合条件的值。

字典推导式

字典推导基本格式:

py
{ key_expr: value_expr for value in collection }
# 或
{ key_expr: value_expr for value in collection if condition }

str1 = 'abcdef'
dict1 = {i: len(i) for i in str1}
print(dict1)
{'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1, 'f': 1}

listdemo = ['Google','Runoob', 'Taobao']
# 将列表中各字符串值为键,各字符串的长度为值,组成键值对
>>> newdict = {key:len(key) for key in listdemo}
>>> newdict
{'Google': 6, 'Runoob': 6, 'Taobao': 6}

# 提供三个数字,以三个数字为键,三个数字的平方为值来创建字典:
>>> dic = {x: x**2 for x in (2, 4, 6)}
>>> dic
{2: 4, 4: 16, 6: 36}
>>> type(dic)
<class 'dict'>

集合推导式

集合推导式基本格式:

py
{ expression for item in Sequence }
{ expression for item in Sequence if conditional }

# 计算数字 1,2,3 的平方数:
setnew = {i**2 for i in (1,2,3)}
setnew
# {1, 4, 9}

a = {x for x in 'abracadabra' if x not in 'abc'}
a
{'d', 'r'}
type(a)
# <class 'set'>

元组推导式(生成器表达式)

元组推导式可以利用 range 区间、元组、列表、字典和集合等数据类型,快速生成一个满足指定需求的元组。 元组推导式基本格式:

py
(expression for item in Sequence )
(expression for item in Sequence if conditional )
# 生成 1~9 的元组:
a = (x for x in range(1,10))
a
<generator object <genexpr> at 0x7faf6ee20a50>  # 返回的是生成器对象
tuple(a)       # 使用 tuple() 函数,可以直接将生成器对象转换成元组
(1, 2, 3, 4, 5, 6, 7, 8, 9)

元组推导式和列表推导式的用法也完全相同,只是元组推导式是用 () 圆括号将各部分括起来,而列表推导式用的是中括号 [],另外元组推导式返回的结果是一个生成器对象。

Python3 迭代器与生成器

迭代器

迭代是访问集合元素的一种方式。 迭代器是一个可以记住 遍历的位置 的对象。 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器 只能往前不会后退。 迭代器有两个基本的方法:iter() 和 next()。

py
list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
print (next(it))   # 输出迭代器的下一个元素     1
print (next(it))   # 输出迭代器的下一个元素      2
# 迭代器对象可以使用常规for语句进行遍历:
#!/usr/bin/python3 
list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
for x in it:
    print (x, end=" ")
    print (next(it))

创建一个迭代器

把一个类作为一个迭代器使用需要在类中实现两个方法 iter() 与 next() 。

如果你已经了解的面向对象编程,就知道类都有一个构造函数,Python 的构造函数为 init(), 它会在对象初始化的时候执行。

  • iter() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 next() 方法并通过 StopIteration 异常标识迭代的完成。
  • next() 方法(Python 2 里是 next())会返回下一个迭代器对象。

StopIteration

StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 next() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。

生成器

在 Python 中,使用了 yield 的函数被称为生成器(generator)。 yield 是一个关键字,用于定义生成器函数, 生成器函数是一种特殊的函数 ,可以在迭代过程中 逐步产生值,而不是一次性返回所有结果。 跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。 当在生成器函数中使用 yield 语句时,函数的执行将会暂停,并将 yield 后面的表达式作为当前迭代的值返回。

然后,每次调用生成器的 next() 方法或使用 for 循环进行迭代时,函数会从上次暂停的地方继续执行,直到再次遇到 yield 语句。这样,生成器函数可以逐步产生值,而不需要一次性计算并返回所有结果。 调用一个生成器函数,返回的是一个迭代器对象。 下面是一个简单的示例,展示了生成器函数的使用:

py
def countdown(n):
    while n > 0:
        yield n
        n -= 1
 
# 创建生成器对象
generator = countdown(5)
 
# 通过迭代生成器获取值
print(next(generator))  # 输出: 5
print(next(generator))  # 输出: 4
print(next(generator))  # 输出: 3
 
# 使用 for 循环迭代生成器
for value in generator:
    print(value)  # 输出: 2 1
# 以上实例中,countdown 函数是一个生成器函数。它使用 yield 语句逐步产生从 n 到 1 的倒数数字。在每次调用 yield 语句时,函数会返回当前的倒数值,并在下一次调用时从上次暂停的地方继续执行。

# 通过创建生成器对象并使用 next() 函数或 for 循环迭代生成器,我们可以逐步获取生成器函数产生的值。在这个例子中,我们首先使用 next() 函数获取前三个倒数值,然后通过 for 循环获取剩下的两个倒数值。

# 生成器函数的优势是它们可以按需生成值,避免一次性生成大量数据并占用大量内存。此外,生成器还可以与其他迭代工具(如for循环)无缝配合使用,提供简洁和高效的迭代方式。

#!/usr/bin/python3
 
import sys
 
def fibonacci(n): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
 
while True:
    try:
        print (next(f), end=" ")
    except StopIteration:
        sys.exit()

Python with 关键字

with 关键字为我们提供了一种优雅的方式来处理文件操作、数据库连接等需要 明确释放资源 的场景。 with 是 Python 中的一个关键字,用于上下文管理协议(Context Management Protocol)。它简化了资源管理代码,特别是那些需要明确释放或清理的资源(如文件网络连接数据库连接等)。

with 语句的基本语法

with 语句的基本形式如下: with expression as variable:

py
file = open('example.txt', 'r')
try:
    content = file.read()
    # 处理文件内容
finally:
    file.close()
# 存在几个问题:
# 容易忘记关闭资源:如果没有 try-finally 块,可能会忘记调用 close()
# 代码冗长:简单的文件操作需要多行代码
# 异常处理复杂:需要手动处理可能出现的异常
with open('example.txt', 'r') as file:
    content = file.read()
    print(content)
# 文件已自动关闭

实际应用场景

py
# 1. 文件操作
# 同时打开多个文件
with open('input.txt', 'r') as infile, open('output.txt', 'w') as outfile:
    content = infile.read()
    outfile.write(content.upper())
# 2. 数据库连接
import sqlite3

with sqlite3.connect('database.db') as conn:
    cursor = conn.cursor()
    cursor.execute('SELECT * FROM users')
    results = cursor.fetchall()
# 连接自动关闭
# 3. 线程锁
import threading

lock = threading.Lock()

with lock:
    # 临界区代码
    print("这段代码是线程安全的")

#  4. 临时修改系统状态
import decimal

with decimal.localcontext() as ctx:
    ctx.prec = 42  # 临时设置高精度
    # 执行高精度计算
# 精度恢复原设置

最佳实践

  1. 优先使用 with 管理资源:对于文件、网络连接、锁等资源,总是优先考虑使用 with 语句
  2. 保持上下文简洁:with 块中的代码应该只包含与资源相关的操作
  3. 合理处理异常:在自定义上下文管理器中,根据需求决定是否抑制异常
  4. 利用多个上下文:Python 允许在单个 with 语句中管理多个资源

总结要点

关键点说明
自动资源管理with 语句确保资源被正确释放
上下文协议需要实现 __enter____exit__ 方法
异常安全即使代码块中出现异常,资源也会被释放
常见应用文件操作、数据库连接、线程锁等
自定义实现可以通过类或 contextlib 创建自定义上下文管理器
with 语句是 Python 中一项强大的特性,它不仅能简化代码,还能提高程序的健壮性。掌握 with 语句的使用和原理,将帮助你写出更专业、更可靠的 Python 代码。

Python3 函数

Python 定义函数使用 def 关键字,一般格式如下:

py
def 函数名(参数列表):
    函数体

默认情况下,参数值和参数名称是按函数声明中定义的顺序匹配起来的。

py
#!/usr/bin/python3
 
# 计算面积函数
def area(width, height):
    return width * height
 
def print_welcome(name):
    print("Welcome", name)
 
print_welcome("Runoob")
w = 4
h = 5
print("width =", w, " height =", h, " area =", area(w, h))

参数传递

在 Python 中,参数传递有两种主要方式:按值传递call by value)和按引用传递call by reference)。

按值传递

按值传递是指将参数的复制一份传递给函数。在函数内部对参数进行修改不会影响到函数外部的变量。 列表,字典, list,dict 等则是可以修改的对象,所以按值传递时,修改的是对象的副本,不会影响到原对象。

py
def func(x):
    x = x + 1
    print("func:", x)
 
a = 10
func(a)
print("a:", a)

按引用传递

按引用传递是指将参数的内存地址传递给函数。在函数内部对参数进行修改会影响到函数外部的变量。 整数、字符串、元组, strings, tuples, 和 numbers 是不可更改的对象, 所以按引用传递时,修改的是对象本身,而不是副本。

py
def func(x):
    x.append(100)
    print("func:", x)
 
a = [1, 2, 3]
func(a)
print("a:", a)

总结

  • 按值传递适用于可变对象(如列表、字典、集合等),不会影响到原对象。
  • 按引用传递适用于不可变对象(如整数、浮点数、字符串、元组等),会影响到原对象。

参数

调用函数时可使用的正式参数类型:

  • 必需参数
  • 关键字参数
  • 默认参数
  • 不定长参数

必需参数

必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。

关键字参数

关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。

使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

以下实例在函数 printme() 调用时使用参数名:

py
#!/usr/bin/python3
 
#可写函数说明
def printinfo( name, age ):
   "打印任何传入的字符串"
   print ("名字: ", name)
   print ("年龄: ", age)
   return
 
#调用printinfo函数
printinfo( age=50, name="runoob" )

默认参数

调用函数时,如果没有传递参数,则会使用默认参数。以下实例中如果没有传入 age 参数,则使用默认值:

py
#!/usr/bin/python3
 
#可写函数说明
def printinfo( name, age=20 ):
   "打印任何传入的字符串"
   print ("名字: ", name)
   print ("年龄: ", age)
   return
 
#调用printinfo函数
printinfo( age=50, name="runoob" )
printinfo( name="runoob" )

不定长参数

你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述 2 种参数不同,声明时不会命名。基本语法如下:

py
def functionname([formal_args,] *var_args_tuple ):
   "函数_文档字符串"
   function_suite
   return [expression]

# 可写函数说明
def printinfo( arg1, *vartuple ):
   "打印任何传入的参数"
   print ("输出: ")
   print (arg1)
   print (vartuple)
 
# 调用printinfo 函数
printinfo( 70, 60, 50 )

参数带两个星号

加了两个星号的参数会以字典的形式导入。 还有一种就是参数带两个星号基本语法如下:

py
def functionname([formal_args,] **var_args_dict ):
   "函数_文档字符串"
   function_suite
   return [expression]
# 可写函数说明
def printinfo( arg1, **vardict ):
   "打印任何传入的参数"
   print ("输出: ")
   print (arg1)
   print (vardict)
 
# 调用printinfo 函数
printinfo( 1, a=2, b=3 )

星号 * 单独出现

声明函数时,参数中星号 可以单独出现,例如: 如果单独出现星号,则星号 * 后的参数必须用关键字传入:

py
def f(a,b,*,c):
    return a+b+c
f(1,2,3)   # 报错
f(1,2,c=3) # 正常

匿名函数

所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。 使用 lambda 来创建匿名函数。

  • lambda 只是一个表达式,函数体比 def 简单很多。
  • lambda 的主体是一个表达式,而不是一个代码块。仅仅能在 lambda 表达式中封装有限的逻辑进去。
  • lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
  • 虽然 lambda 函数看起来只能写一行,却不等同于 C 或 C++ 的内联函数,内联函数的目的是调用小函数时不占用栈内存从而减少函数调用的开销,提高代码的执行速度。

lambda 函数的语法只包含一个语句,如下: lambda [arg1 [,arg2,.....argn]]:expression

py
# 可写函数说明
sum = lambda arg1, arg2: arg1 + arg2
 
# 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))
print ("相加后的值为 : ", sum( 20, 20 ))

return 语句

return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的 return 语句返回 None。之前的例子都没有示范如何返回数值,以下实例演示了 return 语句的用法:

py
# 可写函数说明
def sum( arg1, arg2 ):
   # 返回2个参数的和."
   total = arg1 + arg2
   print ("函数内 : ", total)
   return total
 
# 调用sum函数
total = sum( 10, 20 )
print ("函数外 : ", total)

Python lambda(匿名函数)

Python 使用 lambda 来创建匿名函数。 lambda 函数是一种小型、匿名的、内联函数,它可以具有任意数量的参数,但只能有一个表达式。 匿名函数不需要使用 def 关键字定义完整函数。 lambda 函数通常用于编写 简单的单行的 函数,通常在需要函数作为参数传递的情况下使用,例如在 map()、filter()、reduce() 等函数中。

lambda 函数特点

  • lambda 函数是匿名的,它们没有函数名称,只能通过赋值给变量或作为参数传递给其他函数来使用。
  • lambda 函数通常只包含一行代码,这使得它们适用于编写简单的函数。

lambda 语法格式

lambda arguments: expression

  • lambda是 Python 的关键字,用于定义 lambda 函数。
  • arguments 是参数列表,可以包含零个或多个参数,但必须在冒号(:)前指定。
  • expression 是一个表达式,用于计算并返回函数的结果。
python
x = lambda a, b, c : a + b + c
print(x(5, 6, 2))
# 使用 lambda 函数与 map() 一起,对列表中的每个元素进行平方操作:
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared)  # 输出: [1, 4, 9, 16, 25]
# 使用 lambda 函数与 filter() 一起,筛选偶数:
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)  # 输出:[2, 4, 6, 8]

#使用 reduce() 和 lambda 表达式演示如何计算一个序列的累积乘积:
from functools import reduce 
numbers = [1, 2, 3, 4, 5] 
# 使用 reduce() 和 lambda 函数计算乘积
product = reduce(lambda x, y: x * y, numbers) 
print(product)  # 输出:120

Python 装饰器

装饰器(decorators)是 Python 中的一种高级功能,它允许你动态地修改函数或类的行为。 装饰器是一种函数,它接受一个函数作为参数,并返回一个新的函数或修改原来的函数。 装饰器的语法使用 @decorator_name 来应用在函数或方法上。

Python 还提供了一些内置的装饰器,比如 @staticmethod 和 @classmethod,用于定义静态方法和类方法。

装饰器的应用场景

  • 日志记录: 装饰器可用于记录函数的调用信息、参数和返回值。
  • 性能分析: 可以使用装饰器来测量函数的执行时间。
  • 权限控制: 装饰器可用于限制对某些函数的访问权限。
  • 缓存: 装饰器可用于实现函数结果的缓存,以提高性能。

基本语法

Python 装饰允许在不修改原有函数代码的基础上,动态地增加或修改函数的功能,装饰器本质上是一个接收函数作为输入并返回一个新的包装过后的函数的对象。

py
def decorator_function(original_function):
    def wrapper(*args, **kwargs):
        # 这里是在调用原始函数前添加的新功能
        before_call_code()
        
        result = original_function(*args, **kwargs)
        
        # 这里是在调用原始函数后添加的新功能
        after_call_code()
        
        return result
    return wrapper

# 使用装饰器
@decorator_function
def target_function(arg1, arg2):
    pass  # 原始函数的实现

## 带参数的装饰器
def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("在原函数之前执行")
        func(*args, **kwargs)
        print("在原函数之后执行")
    return wrapper

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

greet("Alice")

类装饰器

除了函数装饰器,Python 还支持类装饰器。 类装饰器(Class Decorator)是一种用于动态修改类行为的装饰器,它接收一个类作为参数,并返回一个新的类或修改后的类。

类装饰器可以用于

  • 添加/修改类的方法或属性
  • 拦截实例化过程
  • 实现单例模式、日志记录、权限检查等功能

类装饰器有两种常见形式

  • 函数形式的类装饰器(接收类作为参数,返回新类)
  • 类形式的类装饰器(实现 call 方法,使其可调用)

函数形式的类装饰器

以下实例给类添加日志功能:

py
def log_class(cls):
    """类装饰器,在调用方法前后打印日志"""
    class Wrapper:
        def **init**(self, *args, **kwargs):
            self.wrapped = cls(*args,**kwargs)  # 实例化原始类

        def __getattr__(self, name):
            """拦截未定义的属性访问,转发给原始类"""
            return getattr(self.wrapped, name)
       
        def display(self):
            print(f"调用 {cls.__name__}.display() 前")
            self.wrapped.display()
            print(f"调用 {cls.__name__}.display() 后")
   
    return Wrapper  # 返回包装后的类

@log_class
class MyClass:
    def display(self):
        print("这是 MyClass 的 display 方法")

obj = MyClass()
obj.display()

内置装饰器

Python 提供了一些内置的装饰器,例如

  1. @staticmethod: 将方法定义为静态方法,不需要实例化类即可调用。
  2. @classmethod: 将方法定义为类方法,第一个参数是类本身(通常命名为 cls)。
  3. @property: 将方法转换为属性,使其可以像属性一样访问。
py
class MyClass:
    @staticmethod
    def static_method():
        print("This is a static method.")

    @classmethod
    def class_method(cls):
        print(f"This is a class method of {cls.__name__}.")

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        self._name = value

# 使用
MyClass.static_method()
MyClass.class_method()

obj = MyClass()
obj.name = "Alice"
print(obj.name)

多个装饰器的堆叠

你可以将多个装饰器堆叠在一起,它们会按照从下到上的顺序依次应用。例如:

py
def decorator1(func):
    def wrapper():
        print("Decorator 1")
        func()
    return wrapper

def decorator2(func):
    def wrapper():
        print("Decorator 2")
        func()
    return wrapper

@decorator1
@decorator2
def say_hello():
    print("Hello!")

say_hello()
# Decorator 1
# Decorator 2
# Hello!

Python __name____main__

1. __name__变量

__name__ 是一个内置变量,用于表示当前模块的名称。 __name__ 的值取决于模块是如何被使用的: 当模块作为主程序运行时:__name__ 的值被设置为 __main__。 当模块被导入时:__name__ 的值被设置为模块的文件名(不包括 .py 扩展名)。

2. __main__ 的含义

__main__ 是一个特殊的字符串,用于表示当前模块是作为主程序运行的。 __main__ 通常与 __name__ 变量一起使用,以确定模块是被导入还是作为独立脚本运行。

3. 使用 if __name__ == "__main__": 的常见模式

在 Python 中,常见的做法是在模块的末尾添加以下代码块:

py
if __name__ == "__main__":
    # 这里的代码只有在模块作为主程序运行时才会执行
    main()

总结

  • __name__ 是一个内置变量,表示当前模块的名称。
  • 当模块作为主程序运行时,__name__ 的值是 __main__
  • 当模块被导入时,__name__ 的值是模块的文件名(不包括 .py 扩展名)。
  • 使用 if __name__ == "__main__": 可以控制模块在被导入时不会执行某些代码,而只有在作为独立脚本运行时才会执行这些代码。

Python3 输入和输出

  • 字符串对象的 rjust() 方法, 它可以将字符串靠右, 并在左边填充空格。
  • 还有类似的方法, 如 ljust() 和 center()。 这些方法并不会写任何东西, 它们仅仅返回新的字符串。
  • zfill(), 它会在数字的左边填充 0, 直到达到指定的宽度。
  • str.format() 的基本使用如下:
  • 可选项 : 和格式标识符可以跟着字段名。 这就允许对值进行更好的格式化。
  • 传入一个字典, 然后使用方括号 [] 来访问键值
py
>>> '12'.zfill(5)
# '00012'
>>> '-3.14'.zfill(7)
# '-003.14'
>>> '3.14159265359'.zfill(5)
# '3.14159265359'

>>> print('{}网址: "{}!"'.format('菜鸟教程', 'www.runoob.com'))
# # 菜鸟教程网址: "www.runoob.com!"
>>> print('{0}{1}'.format('Google', 'Runoob'))
# Google 和 Runoob
>>> print('{1}{0}'.format('Google', 'Runoob'))
# Runoob 和 Google

>>> print('{name}网址: {site}'.format(name='菜鸟教程', site='www.runoob.com'))
# 菜鸟教程网址: www.runoob.com
>>> print('站点列表 {0}, {1}, 和 {other}。'.format('Google', 'Runoob', other='Taobao'))
# 站点列表 Google, Runoob, 和 Taobao。

>>> import math
>>> print('常量 PI 的值近似为 {0:.3f}。'.format(math.pi))
常量 PI 的值近似为 3.142

>>> table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
>>> for name, number in table.items():
...     print('{0:10} ==> {1:10d}'.format(name, number))
... 
# Google     ==>          1
# Runoob     ==>          2
# Taobao     ==>          3

table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
print('Runoob: {0[Runoob]:d}; Google: {0[Google]:d}; Taobao: {0[Taobao]:d}'.format(table))
# Runoob: 2; Google: 1; Taobao: 3
## 也可以通过在 table 变量前使用 ** 来实现相同的功能:
table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
print('Runoob: {Runoob:d}; Google: {Google:d}; Taobao: {Taobao:d}'.format(**table))
# Runoob: 2; Google: 1; Taobao: 3

Python3 File(文件) 方法

Python open() 方法用于打开一个文件,并返回文件对象。

在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError。 **注意:**使用 open() 方法一定要保证关闭文件对象,即调用 close() 方法。

open()

函数常用形式是接收两个参数:文件名(file)和模式(mode)

open(file, mode='r')

完整的语法格式为

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

参数说明

  • file: 必需,文件路径(相对或者绝对路径)。
  • mode: 可选,文件打开模式
  • buffering: 设置缓冲
  • encoding: 一般使用utf8
  • errors: 报错级别
  • newline: 区分换行符
  • closefd: 传入的file参数类型
  • opener: 设置自定义开启器,开启器的返回值必须是一个打开的文件描述符。

Python3 OS 文件/目录方法

os 模块是 Python 标准库中的一个重要模块,它提供了与操作系统交互的功能。

通过 os 模块,你可以执行文件操作、目录操作、环境变量管理、进程管理等任务。

os 模块是跨平台的,这意味着你可以在不同的操作系统(如 Windows、Linux、macOS)上使用相同的代码。

在使用 os 模块之前,你需要先导入它。导入 os 模块的代码如下:

py
import os

# 1. 获取当前工作目录
# os.getcwd() 函数用于获取当前工作目录的路径。当前工作目录是 Python 脚本执行时所在的目录。
# 实例
current_directory = os.getcwd()
print("当前工作目录:", current_directory)
# 2. 改变当前工作目录
# os.chdir(path) 函数用于改变当前工作目录。path 是你想要切换到的目录路径。
# 实例
os.chdir("/path/to/new/directory")
print("新的工作目录:", os.getcwd())
# 3. 列出目录内容
# os.listdir(path) 函数用于列出指定目录中的所有文件和子目录。如果不提供 path 参数,则默认列出当前工作目录的内容。

# 实例
files_and_dirs = os.listdir()
print("目录内容:", files_and_dirs)
# 4. 创建目录
# os.mkdir(path) 函数用于创建一个新的目录。如果目录已经存在,会抛出 FileExistsError 异常。

# 实例
os.mkdir("new_directory")
# 5. 删除目录
# os.rmdir(path) 函数用于删除一个空目录。如果目录不为空,会抛出 OSError 异常。

# 实例
os.rmdir("new_directory")
# 6. 删除文件       
os.remove(path) 函数用于删除一个文件。如果文件不存在,会抛出 FileNotFoundError 异常。

# 实例
os.remove("file_to_delete.txt")
# 7. 重命名文件或目录
# os.rename(src, dst) 函数用于重命名文件或目录。src 是原始路径,dst 是新的路径。

# 实例
os.rename("old_name.txt", "new_name.txt")
# 8. 获取环境变量
# os.getenv(key) 函数用于获取指定环境变量的值。如果环境变量不存在,返回 None。

# 实例
home_directory = os.getenv("HOME")
print("HOME 目录:", home_directory)
# 9. 执行系统命令
# os.system(command) 函数用于在操作系统的 shell 中执行命令。命令执行后,返回命令的退出状态。

# 实例
os.system("ls -l")

Python3 错误和异常

try 语句按照如下方式工作

  • try/except...else...finally:
    • try:执行代码 ;except子句在发生异常时执行; else子句在 try 子句没有发生任何异常时执行;finally子句无论是否发生异常都会执行。
  • 首先,执行 try 子句(在关键字 try 和关键字 except 之间的语句)。
  • 如果没有异常发生,忽略 except 子句,try 子句执行后结束。
  • 如果在执行 try 子句的过程中发生了异常,那么 try 子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符,那么对应的 except 子句将被执行。
  • 如果一个异常没有与任何的 except 匹配,那么这个异常将会传递给上层的 try 中。
  • 一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。
  • 处理程序将只针对对应的 try 子句中的异常进行处理,而不是其他的 try 的处理程序中的异常。
  • 一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,例如:
  • 最后一个except子句可以忽略异常的名称,它将被当作通配符使用。你可以使用这种方法打印一个错误信息,然后再次把异常抛出。
py
import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except (RuntimeError, TypeError, NameError):
    pass
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise

抛出异常

Python 使用 raise 语句抛出一个指定的异常。

raise语法格式如下

raise [Exception [, args [, traceback]]]

py
try:
        raise NameError('HiThere')  # 模拟一个异常。
    except NameError:
        print('An exception flew by!')
        raise
   
# An exception flew by!
# Traceback (most recent call last):
#   File "<stdin>", line 2, in ?
# NameError: HiThere

用户自定义异常

你可以通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承,例如:

py
 class MyError(Exception):
     def __init__(self, value):
         self.value = value
     def __str__(self):
         return repr(self.value)
   
 try:
        raise MyError(2*2)
    except MyError as e:
        print('My exception occurred, value:', e.value)   
# My exception occurred, value: 4
# >>> raise MyError('oops!')
# Traceback (most recent call last):
#   File "<stdin>", line 1, in ?
# __main__.MyError: 'oops!'

Python 类型注解(Type Hints)

类型注解(Type Hints) 在编程中就扮演着类似的角色——它是一种为代码添加"说明标签"的技术,明确地指出变量、函数参数和返回值应该是什么数据类型。

简单来说,类型注解就是在代码中注明数据类型的语法,它的核心目的是:

  • 提高代码可读性:让他人(以及未来的你)一眼就能看懂代码的意图
  • 便于静态检查:在运行代码前,通过工具发现潜在的类型错误
  • 增强IDE支持:让代码编辑器提供更准确的自动补全和提示
  • 提高代码的可维护性:通过类型注解,可以让代码更容易被其他程序员理解和修改
  • 类型注解是可选的,不会影响代码的运行。
  • 类型注解只是一种提示,不会强制类型检查。
  • 类型注解可以在函数定义、变量赋值、类定义等地方使用。
py

# 有类型注解的代码
name: str = "Alice"       # 注解为字符串 (str)
age: int = 30             # 注解为整数 (int)
is_student: bool = False  # 注解为布尔值 (bool)
scores: list = [95, 88, 91] # 注解为列表 (list)

# 没有类型注解
def greet(name):
    return f"Hello, {name}"
# 有类型注解
def greet(name: str) -> str:
    return f"Hello, {name}"
# 有类型注解的函数
def greet(first_name: str, last_name: str) -> str:
    full_name = first_name + " " + last_name
    return "Hello, " + full_name

def add_numbers(a: int, b: int) -> int:
    """将两个整数相加并返回结果"""
    return a + b
# 调用函数
result = add_numbers(5, 3)  # 正确:两个整数
# result = add_numbers("5", "3")  # 可能有问题:虽然能运行,但类型检查器会警告

### 列表、字典等容器类型
from typing import List, Dict, Tuple, Set

# List[int] 表示这是一个只包含整数的列表
numbers: List[int] = [1, 2, 3, 4, 5]
# Dict[str, int] 表示这是一个键为字符串、值为整数的字典
student_scores: Dict[str, int] = {"Alice": 95, "Bob": 88}
# Tuple[int, str, bool] 表示这是一个包含整数、字符串、布尔值的元组
person_info: Tuple[int, str, bool] = (25, "Alice", True)
# Set[str] 表示这是一个只包含字符串的集合
unique_names: Set[str] = {"Alice", "Bob", "Charlie"}

Mypy 进行静态类型检查

pip install mypy

py
# example.py
def add_numbers(a: int, b: int) -> int:
    return a + b

result = add_numbers("5", "3")  # 这里有问题!传入了字符串而不是整数
print(result)

Python3 标准库概览

Python 标准库非常庞大,所提供的组件涉及范围十分广泛,使用标准库我们可以让您轻松地完成各种任务。

以下是一些 Python3 标准库中的模块

  • os 模块:os 模块提供了许多与操作系统交互的函数,例如创建、移动和删除文件和目录,以及访问环境变量等。
  • sys 模块:sys 模块提供了与 Python 解释器和系统相关的功能,例如解释器的版本和路径,以及与 stdin、stdout 和 stderr 相关的信息。
  • time 模块:time 模块提供了处理时间的函数,例如获取当前时间、格式化日期和时间、计时等。
  • datetime 模块:datetime 模块提供了更高级的日期和时间处理函数,例如处理时区、计算时间差、计算日期差等。
  • random 模块:random 模块提供了生成随机数的函数,例如生成随机整数、浮点数、序列等。
  • math 模块:math 模块提供了数学函数,例如三角函数、对数函数、指数函数、常数等。
  • re 模块:re 模块提供了正则表达式处理函数,可以用于文本搜索、替换、分割等。
  • json 模块:json 模块提供了 JSON 编码和解码函数,可以将 Python 对象转换为 JSON 格式,并从 JSON 格式中解析出 Python 对象。
  • urllib 模块:urllib 模块提供了访问网页和处理 URL 的功能,包括下载文件、发送 POST 请求、处理 cookies 等。

Python3 面向对象

面向对象技术简介

  • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
  • 方法:类中定义的函数。
  • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
  • 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
  • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
  • 局部变量:定义在方法中的变量,只作用于当前实例的类。
  • 实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用 self 修饰的变量。
  • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
  • 实例化:创建一个类的实例,类的具体对象。
  • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
py
#!/usr/bin/python3
 
#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))
 
#单继承示例
class student(people):
    grade = ''
    def __init__(self,n,a,w,g):
        #调用父类的构函
        people.__init__(self,n,a,w)
        self.grade = g
    #覆写父类的方法
    def speak(self):
        print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))
 
#另一个类,多继承之前的准备
class speaker():
    topic = ''
    name = ''
    def __init__(self,n,t):
        self.name = n
        self.topic = t
    def speak(self):
        print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))
 
#多继承
class sample(speaker,student):
    a =''
    def __init__(self,n,a,w,g,t):
        student.__init__(self,n,a,w,g)
        speaker.__init__(self,n,t)
 
test = sample("Tim",25,80,4,"Python")
test.speak()   #方法名同,默认调用的是在括号中参数位置排前父类的方法

类的专有方法

  • __init__ : 构造函数,在生成对象时调用
  • __del__ : 析构函数,释放对象时使用
  • __repr__ : 打印,转换
  • __setitem__ : 按照索引赋值
  • __getitem__ : 按照索引获取值
  • __len__ : 获得长度
  • __cmp__ : 比较运算
  • __call__ : 函数调用
  • __add__ : 加运算
  • __sub__ : 减运算
  • __mul__ : 乘运算
  • __truediv__ : 除运算
  • __mod__ : 求余运算
  • __pow__ : 乘方