python - 类范围内的闭包

标签 python class scope

据我了解,函数和类作用域的行为几乎相同:

>>> def x():
...     a = 123
...     print (locals())
... 
>>> x()
{'a': 123}


>>> class x():
...     a = 123
...     print (locals())
... 
{'a': 123, '__module__': '__main__'}

然而,当我定义一个闭包时,行为是不同的。正如预期的那样,函数只是返回本地绑定(bind):
>>> def x():
...     a = 123
...     t = lambda: a
...     return t
... 
>>> x()()
123

而在一个类中,绑定(bind)似乎丢失了:
>>> 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

谁能解释这种差异?

最佳答案

类作用域是一个临时作用域,它只在执行类定义主体时存在。结果 dict用于创建类命名空间,__dict__类的。

就类中定义的函数而言,下一个“向上”范围是 class 的范围。定义本身。

以下工作正常:

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

这记录在 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.



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.



强调我的;执行框架是临时范围。

关于python - 类范围内的闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13381861/

相关文章:

python - 我写了这段代码,但小的改动造成了一些差异并产生了错误

python - 如何从作为参数传递的类初始化对象

python - 如何为微服务创建 Graphql 服务器?

python - GStreamer错误 "assertion ' GST_IS_ELEMENT(链接元素时src )' failed"

javascript - 从我的网页访问 Flask 服务器

python - Python中定义类时,如何给多个变量赋一个值?

c++ - 将一个类对象的指针赋值给另一个类对象c++

swift - 定义一个在 Swift 中调用自定义函数的中缀运算符

c++ - typedef 的类型作为成员函数的返回类型不可见

java - 什么相当于封装包内部功能的包私有(private)接口(interface)?