2
>>> 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() 方法可以改变非全局变量,而 += 运算符不能?据我了解,只要函数不分配变量,它就可以在没有全局指定的情况下读取它。但在这种情况下,函数确实设置了值。

4

1 回答 1

5

它不设置值,它修改现有值。在 Python 中,将名称绑定到值是一回事,而修改(或改变)值是另一回事。

真正的问题是为什么+= 不起作用,因为对于列表,此操作被定义为还就地修改列表。答案就是,因为那个操作符看起来像赋值,所以为了范围和绑定的目的,决定让它像赋值一样。 文档说(强调):

扩充赋值计算目标(与普通赋值语句不同,不能解包)和表达式列表,对两个操作数执行特定于赋值类型的二元运算,并将结果分配给原始目标

换句话说,增强赋值包括作为操作一部分的赋值,因此适用正常的范围/绑定规则。由于目标被评估为目标,如果它是一个函数,它被视为一个局部变量。所以当x是一个列表时,x += newList实际上就像:

x.extend(newList)
x = x

更一般地说,增强赋值可以就地修改操作数,但它仍然会尝试将结果值重新绑定到原始变量。所以x += other本质上是这样的:

y = x.__iadd__(other)
x = y
于 2012-11-24T19:36:33.100 回答