The variable bar
in the function definition below is interpreted as a global variable because there is no definition of bar
in the function block.
def foo():
print(bar)
The code below succeeds because the global variable bar
is defined before calling foo
.
bar = 4
def foo():
print(bar)
foo() # => 4
You can see the global variables of foo
in the attribute co_names
of the code object of foo
.
foo.__code__.co_names # => ('print', 'bar')
By the way, in Python's official documentation, co_names
is written as the local variable name tuple
, but (local variable name) (Excluding free variables) Name error.
The bar
in the function definition below is interpreted as a local variable because the bar
is defined in the function block.
def foo():
print(bar)
bar = 3
foo.__code__.co_names # => ('print',)
You can see the local variables of foo
in the attribute co_varnames
of the code object of foo
.
foo.__code__.co_varnames # => ('bar',)
This interpretation is determined when the function definition is made, so even if there is a bar
before the definition of bar
, it will not be interpreted as a global variable, and an error will occur as follows.
bar = 4
def foo():
print(bar)
bar = 3
foo()
# => UnboundLocalError: local variable 'bar' referenced before assignment
In other words, the name in the function block is determined to be a global variable or a local variable (or a free variable) at the stage of function definition, and it is not rebound from a global variable to a local variable at the time of assignment to the name.
In addition, comprehensions such as lists introduce a new scope, but only the iterables corresponding to the first for
are interpreted in the outer scope. The example below succeeds, because of the three bar
s in the list comprehension, the rightmost bar
is interpreted as the scope of foo
, that is, the global variable bar
.
bar = range(3)
def foo():
print([bar for bar in bar])
foo() # => [0, 1, 2]
Recommended Posts