链式赋值是如何工作的?
这里有一句话:
>>> x = y = somefunction()
这和
>>> y = somefunction()
>>> x = y
是一样的
x = y = somefunction()
和
x = somefunction()
y = somefunction()
吗?
根据我的理解,它们应该是一样的,因为 somefunction
只能返回一个确切的值。
6 个回答
16
如果somefunction()
每次被调用时返回的值都不一样,那会怎么样呢?
import random
x = random.random()
y = random.random()
95
从左边开始
x = y = some_function()
等同于
temp = some_function()
x = temp
y = temp
注意顺序。最左边的目标会先被赋值。(在C语言中,有类似的表达式可能会以相反的顺序进行赋值。)根据Python的赋值文档:
...将单个结果对象从左到右赋值给每个目标列表。
反汇编显示如下:
>>> def chained_assignment():
... x = y = some_function()
...
>>> import dis
>>> dis.dis(chained_assignment)
2 0 LOAD_GLOBAL 0 (some_function)
3 CALL_FUNCTION 0
6 DUP_TOP
7 STORE_FAST 0 (x)
10 STORE_FAST 1 (y)
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
注意:同一个对象总是被赋值给每个目标。因此,正如@Wilduck和@andronikus所指出的,你可能永远不想这样做:
x = y = [] # Wrong.
在上面的例子中,x和y指向的是同一个列表。因为列表是可变的,所以对x的添加操作会似乎影响到y。
x = [] # Right.
y = []
现在你有两个名字,分别指向两个不同的空列表。
51
如果somefunction
返回的是一个可以改变的值,它们的工作方式可能就不一样了。想想看:
>>> def somefunction():
... return []
...
>>> x = y = somefunction()
>>> x.append(4)
>>> x
[4]
>>> y
[4]
>>> x = somefunction(); y = somefunction()
>>> x.append(3)
>>> x
[3]
>>> y
[]