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 bars 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