El problema es que cuando asigna un nombre de variable dentro de una función, Python supone que está intentando crear una nueva variable local que enmascarará una variable con un nombre similar en el ámbito externo. Dado que +=
tiene que obtener el valor de mylist
antes de que pueda modificarlo, se queja, porque la versión local de mylist
aún no está definida. MRAB's answer da una explicación clara de la semántica.
Por otro lado, cuando hace mylist.__iadd__([1])
, no está asignando un nuevo nombre de variable dentro de la función. Solo está usando un método incorporado para modificar un nombre de variable ya asignado. Siempre que no intente asignar un nuevo valor al mylist
, no tendrá problemas. Por la misma razón, la línea mylist[0] = 5
también funcionaría dentro de inner
si la definición de mylist
en outer
fuera mylist = [1]
.
Nota sin embargo que si intenta asignar un nuevo valor a mylist
en cualquier lugar de la función, mylist.__iadd__([1])
será bien omita:
>>> outer()
>>> def outer():
... mylist = []
... def inner():
... mylist.__iadd__([1])
... mylist = []
... inner()
...
>>> outer()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in outer
File "<stdin>", line 4, in inner
UnboundLocalError: local variable 'mylist' referenced before assignment
Si desea asignar un nuevo valor a una variable de un ámbito contenedor , en 3.0+ puede usar nonlocal
, de la misma manera que usaría global
para asignar un nuevo valor a una variable en el ámbito global. Así que en lugar de esto:
>>> mylist = []
>>> def inner():
... global mylist
... mylist += [1]
...
>>> inner()
>>> mylist
[1]
Para ello:
¿Existe una razón por la que no se podía usar '.extend() ¿? – Amber
o '.append()', si solo está agregando un valor. –
Esos son específicos de listas, hay soluciones generales para el problema. – agf