根据3.6.0文件:
cpython实现细节:在cpython 3.6及更高版本中,__class__
单元格作为类中的__classcell__项传递给元类
命名空间。如果存在,则必须将其传播到type.__new__
调用以正确初始化类。没有做到
这样会导致python 3.6中的DeprecationWarning
RuntimeWarning未来。
有人能提供一个正确的例子吗?
一个实际需要它的例子?

最佳答案

如果使用零参数supersuper().__method__(args)依赖于类体内的__class__可用或引用,则会引发警告。
文本本质上说的是,如果您定义了一个自定义的元类,并在将其传递给__class__之前篡改了所得到的名称空间,那么就需要这样做。您需要小心,并始终确保在您的type.__new__中将__classcell__传递给type.__new__
也就是说,如果要创建一个新的花式名称空间来传递,请始终检查在创建的原始名称空间中是否定义了metaclass.__new__,然后添加它:

class MyMeta(type):
    def __new__(cls, name, bases, namespace):
        my_fancy_new_namespace = {....}
        if '__classcell__' in namespace:
             my_fancy_new_namespace['__classcell__'] = namespace['__classcell__']
        return super().__new__(cls, name, bases, my_fancy_new_namespace)

您在注释中链接的文件实际上是许多尝试修补程序中的第一个,__classcell__是最后一个修补程序,它来自于Issue 23722
在使用它修复Python 3.6中引入的问题的pull request made to Django中可以看到正确执行此操作的示例:
new_attrs = {'__module__': module}
classcell = attrs.pop('__classcell__', None)
if classcell is not None:
    new_attrs['__classcell__'] = classcell
new_class = super_new(cls, name, bases, new_attrs)

在传递给issue23722_classcell_reference_validation_v2.diff之前,只需将__classcell__添加到新的命名空间中。

关于python - 为Python 3.6元类提供__classcell__示例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41343263/

10-12 23:17