Closures in a class scope

青春壹個敷衍的年華 提交于 2019-12-07 04:14:26

问题


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?


回答1:


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:

>>> def foo():
...     spam = 'eggs'
...     class Bar(object):
...         def baz(self): return spam
...     return Bar()
... 
>>> foo().baz()
'eggs'

This is documented in pep 227:

Names in class scope are not accessible. Names are resolved in the innermost enclosing function scope. If a class definition occurs in a chain of nested scopes, the resolution process skips class definitions.

and in the class compound statement documentation:

The class’s suite is then executed in a new execution frame (see section Naming and binding), using a newly created local namespace and the original global namespace. (Usually, the suite contains only function definitions.) When the class’s suite finishes execution, its execution frame is discarded but its local namespace is saved. [4] A class object is then created using the inheritance list for the base classes and the saved local namespace for the attribute dictionary.

Emphasis mine; the execution frame is the temporary scope.



来源:https://stackoverflow.com/questions/13381861/closures-in-a-class-scope

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!