我最近逐步完成了CPython源代码,特别是在编译期间查看了类的symbol table entry。
我碰到了typedef struct _symtable_entry
结构的以下条目:
[-- other entries --]
unsigned ste_needs_class_closure : 1; /* for class scopes, true if a
closure over __class__
should be created */
[-- other entries --]
我似乎无法理解它,也无法找到实际设置ste_needs_class_closure == 1
的python代码示例。在其他失败的尝试中,我尝试了以下内容:
class foo:
y = 30
def __init__(self):
self.x = 50
def foobar(self):
def barfoo():
print(self.x)
print(y)
return barfoo
但即使它执行,执行期间ste_needs_class_closure
的值为0
而不是1
,正如我希望的那样。
实际改变此值的函数是drop_class_free
,这对此没什么帮助。不幸的是,它也没有任何赞美它的评论。
它实际上在analyze_block
中使用,评论为:
/* Check if any local variables must be converted to cell variables */
我可以理解为一个概念,但找不到它发生的例子。
我试过搜索the changelog for Python 3.4,这个成员首次出现的版本但没有找到对它的引用。
那么,任何人都可以解释闭包__class __ 的含义,即什么时候类的局部变量转换为单元格变量?理想情况下,在执行过程中实际显示此行为的示例将非常棒。
答案 0 :(得分:2)
Github’s blame view for that line of code告诉我们它已添加到this commit中,引用Issue #12370:防止类主体干扰__class__
闭包。
从错误报告中,我们试图解决的问题类型的一个例子是:
在Python 3中,以下代码打印
False
因为使用了super()
导致__class__
描述符被省略 类命名空间。删除super
的使用,然后打印True
。class X(object): def __init__(self): super().__init__() @property def __class__(self): return int print (isinstance(X(), int))
(请注意,此代码使用new super()。)
关于补丁的功能,也来自错误报告:
补丁基本上会导致以下类声明:
class C(A, B, metaclass=meta): def f(self): return __class__
大致如下编译:
def _outer_C(*__args__, **__kw__): class _inner_C(*__args__, **__kw__): def f(self): return __class__ __class__ = _inner_C return _inner_C C = _outer_C(A, B, metaclass=meta)
...虽然稍后的一些讨论表明__args__
和__kw__
的处理可能在最终补丁中发生了变化。