I would like to know details about why this doesn’t work as expected:
def outer():
mylist = []
def inner():
mylist += [1]
inner()
outer()
Especially because mylist.__iadd__([1]) works fine.
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
The problem is that when you assign to a variable name inside a function, Python assumes you’re trying to create a new local variable that will mask a similarly-named variable in outer scope. Since
+=has to get the value ofmylistbefore it can modify it, it complains, because the local version ofmylistisn’t yet defined. MRAB’s answer gives a clear explanation of the semantics.On the other hand, when you do
mylist.__iadd__([1]), you aren’t assigning a new variable name inside the function. You’re just using a built-in method to modify an already-assigned variable name. As long as you don’t try to assign a new value tomylist, you won’t have a problem. For the same reason, the linemylist[0] = 5would also work insideinnerif the definition ofmylistinouterweremylist = [1].Note however that if you do try to assign a new value to
mylistanywhere in the function,mylist.__iadd__([1])will indeed fail:If you want to assign a new value to a variable from a containing scope, in 3.0+ you can use
nonlocal, in just the way you’d useglobalto assign a new value to a variable in global scope. So instead of this:You do this: