根据 3.6.0 文档:
CPython 实现细节:在 CPython 3.6 及更高版本中,单元格作为类命名空间中的条目
__class__
传递给元类。__classcell__
如果存在,则必须将其传播到type.__new__
调用才能正确初始化类。如果不这样做,将导致DeprecationWarning
Python 3.6 中RuntimeWarning
的 a 和未来的 a。
有人可以提供一个正确执行此操作的示例吗?
一个实际需要的例子?
根据 3.6.0 文档:
CPython 实现细节:在 CPython 3.6 及更高版本中,单元格作为类命名空间中的条目
__class__
传递给元类。__classcell__
如果存在,则必须将其传播到type.__new__
调用才能正确初始化类。如果不这样做,将导致DeprecationWarning
Python 3.6 中RuntimeWarning
的 a 和未来的 a。
有人可以提供一个正确执行此操作的示例吗?
一个实际需要的例子?
如果您使用依赖于类主体内__class__
可用或引用的 super ,则会引发警告。__class__
文本本质上说的是,如果您定义一个自定义元类并在将其传递给type.__new__
. 您需要小心,并始终确保您传递__classcell__
到type.__new__
您的metaclass.__new__
.
也就是说,如果您创建一个新的花哨的命名空间来传递,请始终检查是否__classcell__
在创建的原始命名空间中定义并添加它:
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)
您在评论中链接的文件实际上是许多尝试的补丁中的第一个,issue23722_classcell_reference_validation_v2.diff
是最终的补丁,来自Issue 23722。
在向 Django 发出的拉取请求中可以看到一个正确执行此操作的示例,该请求使用它来修复 Python 3.6 中引入的问题:
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)
__classcell__
只是在传递给type.__new__
.