为Python3.6元类提供_classcell__;示例

为Python3.6元类提供_classcell__;示例,python,python-3.x,class,metaclass,python-3.6,Python,Python 3.x,Class,Metaclass,Python 3.6,根据3.6.0文档: CPython实现细节:在CPython 3.6及更高版本中,\uuuu类 单元格作为类中的\uuuu类cell\uuuu项传递给元类 命名空间。如果存在,则必须将其传播到类型。\uuuuu new\uuuuu 调用以正确初始化类。做不到 因此,在Python3.6中会出现弃用警告,以及 RuntimeWarning以后 有人能提供一个正确的例子吗 实际需要它的示例?如果您使用依赖于\uuuuuu class\uuuuu可用或在类正文中引用\uuuuuu class\uuu

根据3.6.0文档:

CPython实现细节:在CPython 3.6及更高版本中,
\uuuu类
单元格作为类中的
\uuuu类cell\uuuu
项传递给元类 命名空间。如果存在,则必须将其传播到
类型。\uuuuu new\uuuuu
调用以正确初始化类。做不到 因此,在Python3.6中会出现
弃用警告
,以及
RuntimeWarning
以后

有人能提供一个正确的例子吗


实际需要它的示例?

如果您使用依赖于
\uuuuuu class\uuuuu
可用或在类正文中引用
\uuuuuu class\uuuuuu
的super,则会发出警告

文本本质上说的是,如果您定义了一个自定义的元类,并在将其传递给
类型之前篡改了您得到的名称空间,那么就需要这样做。您需要小心,始终确保将
\uu classcell\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>传递给
类型

也就是说,如果您创建了一个新的奇特名称空间来传递,请始终检查在创建的原始名称空间中是否定义了
\uu classcell\uuuu
,并添加它:

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)
您在注释中链接的文件实际上是许多尝试的修补程序中的第一个,是在中创建的最后一个修补程序

可以在一个示例中看到正确执行此操作的示例,该示例使用此操作来修复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)

\uuuuuu classcell\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu的一些想法。这很可能是因为以前不可能调用元类方法本身内部使用
super()
的任何类方法。更可能的是,Python3.6中新的
\uuuuuu init\u子类
机制需要它。@jsbueno是的,
\uuuuuu init\u子类
带有自定义元类。如果您使用
类型
您很好。@JimFasarakis Hilliard您能提供一个参考或简单的示例来说明自定义名称空间吗?