1. 赋值语句
赋值语句用于将名称(重)绑定到特定值,以及修改属性或可变对象的成员项。
x = 5 # 名字x 绑定到整数5上
y = 'hello' # 名字y 绑定到字符串上
z = [1, 2, 3, 4] # 名字z 绑定到列表上
赋值语句会对指定的表达式列表进行求值(注意这可能为单一表达式或是由逗号分隔的列表,后者将产生一个元组)并将单一结果对象从左至右逐个赋值给目标列表。
x = (16 + (8 ** 2 - 4 * 6 * 2) ** 0.5) / (2 * 5)
print(x) # 2.0
对象赋值的目标对象可以包含于圆括号、方括号、大括号或引号内,如果目标列表为后面不带逗号、可以包含于圆括号内的单一目标,则将对象赋值给该目标。否则该对象必须为具有与目标列表相同项数的可迭代对象,这些项将按从左至右的顺序被赋值给对应的目标。
x = (1)
print(x) # 1
x = (1,)
print(x) # (1,),带逗号时值为元组
x = (1, 2, 3)
print(x) # (1, 2, 3),左侧一个名字时输出一个对象
x, y = (1, 2)
print(x, y) # 1 2,分别输出对象中元素,要求右侧对象中元素数量与左侧变量数量相同
x, y = {1, 2}
print(x, y) # 1 2,要求右侧对象中元素数量与左侧变量数量相同
x, y, z = 'abc'
print(x, y, z) # a b c,要求右侧对象中字符数量与左侧变量数量相同
如果目标列表包含一个带有星号前缀的目标,这称为“加星”目标:则该对象至少必须为与目标列表项数减一相同项数的可迭代对象。 该可迭代对象前面的项将按从左至右的顺序被赋值给加星目标之前的目标。 该可迭代对象末尾的项将被赋值给加星目标之后的目标。 然后该可迭代对象中剩余项的列表将被赋值给加星目标(该列表可以为空)
x = [0, 1]
i = 0
i, x[i] = 1, 2 # i, x[i] 同时赋值
print(i, x) # 1 [0, 2]
如果该名称已经被绑定则将被重新绑定。 这可能导致之前被绑定到该名称的对象的引用计数变为零。如果该对象为属性引用:引用中的原型表达式会被求值。 它应该产生一个具有可赋值属性的对象。
2. 增强赋值语句
python的增强赋值语句是从C语言中借鉴来的,它有输入更少,执行更快,有优化技术自行选择等优点
常用的增强赋值语句:
符号 | 增强赋值语句 | 赋值语句 |
---|---|---|
+= | x += y | x = x + y |
-= | x -= y | x = x - y |
*= | x *= y | x = x * y |
/= | x /= y | x = x / y |
//= | x //= y | x = x // y |
%= | x %= y | x = x % y |
**= | x **= y | x = x ** y |
增强赋值语句还有:
"+=" x += y x = x + y
"-=" x -= y x = x - y
"*=" x *= y x = x * y
"/=" x /= y x = x / y
"//=" x //= y x = x // y
"%=" x %= y x = x % y
"**=" x **= y x = x ** y
"@=" x @= y x = x @ y
">>=" x >>= y x = x >> y
"<<=" x <<= y x = x << y
"&=" x &= y x = x & y
"^=" x ^= y x = x ^ y
"|=" x |= y x = x | y
增强赋值语句就是在单个语句中将二元运算和赋值语句合为一体。
增强赋值语句将对目标和表达式列表求值(与普通赋值语句不同的是,前者不能为可迭代对象拆包)
x = [1, 2]
x += range(3,5) # 为可迭代对象拆包
print(x, id(x)) # [1, 2, 3, 4] 2112894448384
x += {6,7} # 为可迭代对象拆包
print(x, id(x)) # [1, 2, 3, 4, 6, 7] 2112894448384
x += [8, 9] # 为可迭代对象拆包
print(x, id(x)) # [1, 2, 3, 4, 6, 7, 8, 9] 2112894448384
x += 'Tom' # 为可迭代对象拆包
print(x, id(x)) # [1, 2, 3, 4, 6, 7, 8, 9, 'T', 'o', 'm'] 2112894448384
x = [1, 2, 3]
# x = x + range(4) # 不能为可迭代对象拆包
# TypeError: can only concatenate list (not "range") to list
对两个操作数相应类型的赋值执行指定的二元运算,并将结果赋值给原始目标。 目标仅会被求值一次。
增强赋值语句例如 x += 1 可以改写为 x = x + 1 获得类似但并非完全等价的效果。
在增强赋值的版本中,若左侧为可变数据类型,实际的运算是原地直接修改原对象,也就是说并不是创建一个新对象并将其赋值给目标,这种方式速度较快,增强赋值运算会默认选择速度较快的方式。
x = [1, 2, 3]
y = [4, 5]
print(x, id(x)) # [1, 2, 3] 2546413777664
x = x + y # 产生新对象
print(x, id(x)) # [1, 2, 3, 4, 5] 2546413763392
x = [1, 2, 3]
y = [4, 5]
print(x, id(x)) # [1, 2, 3] 2546413777664
x += y # 未产生新对象,原地操作
print(x, id(x)) # [1, 2, 3, 4, 5] 2546413777664
x = [1, 2, 3]
y = [4, 5]
print(x, id(x)) # [1, 2, 3] 2546413760448
x.extend(y) # 未产生新对象,原地操作
print(x, id(x)) # [1, 2, 3, 4, 5] 2546413760448
不同于普通赋值,增强赋值会在对右手边求值 之前 对左手边求值。 例如,a[i] += f(x) 首先查找 a[i],然后对 f(x) 求值并执行加法操作,最后将结果写回到 a[i]。
3. 赋值表达式
赋值表达式把一个表达式的值赋给一个标识符,返回表达式的值
常用于处理分块的文件流量:
while chunk := file.read(9000): # 循环读入数据,读入非空时执行循环
process(chunk)
等效于以下代码
while True:
chunk = file.read(9000)
if chunk: # 读入数据非空时执行循环
process(chunk)
while user_name := input(): # 输入非空字符串时循环输出,输入回车时结束循环
print(user_name)
等效于以下代码
while True:
user_name = input()
if user_name: # 输入非空字符串时输出,输入回车时结束循环
print(user_name)
处理匹配的正则表达式时
if matching := pattern.search(data):
do_something(matching)
相当于
matching = pattern.search(data)
if matching:
do_something(matching)