>>> 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]
Why can the list extend() method alter the non-global variable, but the += operator cannot? From what I understand, as long as the function doesn’t assign the variable, it can read it without the global designation. but in this case the function does set the value.
It doesn’t set the value, it modifies the existing value. In Python binding a name to a value is one thing, and modifying (or mutating) a value is another thing.
The real question is why
+=doesn’t work, since for lists this operation is defined to also modify the list in-place. The answer is just that, because that operator looks like assignment, it was decided to make it act like assignment for scoping and binding purposes. The documentation says (emphasis added):In other words, augmented assignment includes an assignment as part of the operation, so the normal scoping/binding rules apply. Since the target is evaluated as a target, if it’s a function it’s treated as a local variable. So when
xis a list,x += newListis effectively like:More generally, augmented assignment can modify the operand in-place, but it still then attempts to rebind the resulting value to the original variable. So
x += otherworks essentially like: