链式赋值是如何工作的?

61 投票
6 回答
24090 浏览
提问于 2025-04-17 03:22

这里有一句话:

>>> 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
[]

撰写回答