The last paragraph of https://docs.python.org/3/reference/executionmodel.html#resolution-of-names says
Class definition blocks and arguments to exec() and eval() are special in the context of name resolution. A class definition is an executable statement that may use and define names. These references follow the normal rules for name resolution with an exception that unbound local variables are looked up in the global namespace.
What does the last sentence of the quoted text mean? At first I inferred from it that the following code will print 1
a = 1
def foo():
a = 2
def bar():
class Bar:
b = a
print(Bar.b)
bar()
foo()
but I was wrong - a module consisting of the code above, when run, prints 2
, i.e. the name a
in the class definition, even though it's not bound in the class definition block and not bound in the local block just outside of it, isn't looked up in the global namespace, contrary to what the docs say.
I tried another code snippet described below (using a del
statement, which is a construct that binds the variable in it)
a = 1
def foo():
a = 2
def bar():
class Bar:
del a
print(Bar.b)
bar()
foo()
but the del
statement raises NameError: name 'a' is not defined
.
So, I don't understand, what does that sentence mean?
A local variable of a scope is any name defined anywhere in this scope. Notably, the variable itself is local, not the value assigned to it - a local variable can exist before or regardless of assignment.
>>> def foo(): # new function scope
... a = 3 # local variable `a`
... b: int # local variable `b`
... c = 3 # local variable `c`
... del c
... print(x)
... x = 3 # local variable `x`
... foo()
UnboundLocalError: local variable 'x' referenced before assignment
An unbound local variable is such a local variable with no value bound to it. In the above example, all of b
, c
and x
are unbound at some point.
Neither of your examples access an unbound local variable. Both lookup the name a
, but never assign to it.
In a function block, referencing unbound local variables is an error, namely UnboundLocalError
. It does not matter whether that name exists in an enclosing scope as well.
>>> x = 1
>>> def foo():
... b = x # local variable is looked up locally
... x = 2 # make `x` a local variable
... foo()
UnboundLocalError: local variable 'x' referenced before assignment
In a class block, referencing unbound local variables falls back to a lookup in the global scope. This may or may not succeed.
>>> x = 1
>>> class Foo:
... b = x # local variable is looked up locally *or globally*
... x = 2 # make `x` a local variable
... print(Foo.b, Foo.x)
1 2
>>> class Foo:
... b = y # local variable is looked up locally *or globally*
... y = 2 # make `y` a local variable
... print(Foo.b, Foo.y)
NameError: name 'y' is not defined