根据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/