From my understanding, function and class scopes behave pretty much the same:
>>> def x():
... a = 123
... print (locals())
...
>>> x()
{'a': 123}
>>> class x():
... a = 123
... print (locals())
...
{'a': 123, '__module__': '__main__'}
When, however, I define a closure, behaviors are different. A function simply returns the local binding, as expected:
>>> def x():
... a = 123
... t = lambda: a
... return t
...
>>> x()()
123
whereas in a class the binding appears to be lost:
>>> class x():
... a = 123
... t = lambda self: a
...
>>> x().t()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in <lambda>
NameError: global name 'a' is not defined
Can anyone explain the discrepancy?
The class scope is a temporary scope, it only exists while executing the body of the class definition. The resulting
dict
is used to create the class namespace, the__dict__
of the class.As far as functions defined in a class are concerned, the next scope 'up' is the scope of the
class
definition itself.The following works fine:
This is documented in pep 227:
and in the
class
compound statement documentation:Emphasis mine; the execution frame is the temporary scope.