Why is the following code invalid:
def foo1(x=5):
def bar():
if x == 5:
x = 6
print(x)
bar()
While this cod
Python needs first to detect what variables are local, and which variable are fetched from an outer scope. In order to do that it looks for assignments, like:
def foo1(x=5):
def bar():
if x == 5:
x = 6 # an assignment, so local variable
print(x)
bar()
The point is, that the assignment can happen anywhere. For instance on the last line. Nevertheless, from the moment there is an assignment somewhere x
is local. So in your first code fragment, x
is a local variable. But you fetch it before it is assigned (bounded), so Python will error on it.
In python-3.x you can use the nonlocal
keyword to access x
from an outer scope:
def foo1(x=5):
def bar():
nonlocal x
if x == 5:
x = 6
print(x)
bar()
For python-2.x, you can for instance assign the variable to the function, like:
def foo1(x=5):
def bar():
if bar.x == 5:
bar.x = 6
print(bar.x)
bar.x = x
bar()
Note however that the two are not equivalent. Since in the former if you alter x
, it will be alter the x
in the foo1
scope as well. In the latter example you only modify bar.x
. Of course if these are mutable objects, you alter the same object.