闭包和__class__属性

5

最近我在浏览CPython源代码,具体来说是在编译过程中查看类的符号表项

我遇到了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 */

我可以理解这个概念,但找不到相关的例子。

我尝试搜索了Python 3.4的更新日志,这是该成员首次出现的版本,但没有找到任何相关的参考。

所以,有谁能解释一下闭包覆盖 __class__是什么意思?也就是说,在什么情况下类的局部变量会被转换为单元格变量?理想情况下,一个在执行过程中能够看到这种行为的实际例子将会非常好。

1个回答

2
这段文本的英译中文如下:

Github中该行代码的责任视图显示它是在这个提交中添加的,该提交引用了问题#12370:防止类体干扰__class__闭包。

从错误报告中,这个修复尝试解决的问题类型的一个例子是:

In Python 3 the following code prints False because the use of super() has caused the __class__ descriptor to be omitted from the class namespace. Remove the use of super and it prints True.

class X(object):
    def __init__(self):
        super().__init__()

    @property
    def __class__(self):
        return int

print (isinstance(X(), int))
(注意,此代码使用 new super()。)
关于这个补丁的功能,同样来自错误报告:

The patch basically causes the following class statement:

class C(A, B, metaclass=meta):
    def f(self):
        return __class__

To be compiled approximately like this:

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__的方式可能已经改变。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接