>>> x = []
>>> y = [1,2,3]
>>> def func1(L):
...     x+=L
...
>>> def func2(L):
...     x.extend(L)
...
>>> func1(y)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in func1
UnboundLocalError: local variable 'x' referenced before assignment
>>> func2(y)
>>> x
[1, 2, 3]

为什么list extend()方法可以更改非全局变量,而“+”运算符不能?据我所知,只要函数不分配变量,它就可以在没有全局指定的情况下读取变量。但在这种情况下,函数会设置值。

最佳答案

它不设置值,它修改现有值。在Python中,将名称绑定到值是一回事,而修改(或变异)值是另一回事。
真正的问题是为什么+=不起作用,因为对于lists,这个操作被定义为同时修改列表。答案是,因为那个操作符看起来像赋值,所以决定让它像赋值一样用于范围界定和绑定。The documentation说(强调的是):
扩展赋值计算目标(与普通赋值语句不同,它不能是解包语句)和表达式列表,执行特定于两个操作数上赋值类型的二进制操作,并将结果赋给原始目标。
换言之,扩展赋值包括作为操作一部分的赋值,因此应用常规范围/绑定规则。由于目标是作为目标计算的,如果它是一个函数,它将被视为一个局部变量。所以当x是一个列表时,x += newList实际上就像:

x.extend(newList)
x = x

一般来说,扩展赋值可以就地修改操作数,但它仍然尝试将结果值重新绑定到原始变量。因此x += other的工作原理如下:
y = x.__iadd__(other)
x = y

关于python - 为什么可以在没有全局指定的情况下扩展修改值?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13544811/

10-12 22:46
查看更多