使用type()手动创建新类时,将子类__module__设置为元类模块 [英] subclass __module__ set to metaclass module when manually creating new class with type()
问题描述
在下面的示例中,新创建的子类最终是元类__module__
,而不是父类的模块.我只在使用ABCMeta
时看到过这种情况,所以它可能是特定于该模块的东西,有人知道会发生什么情况吗?
In the following example, the newly created subclass ends up being the metaclass __module__
rather than the parent classes' module. I've only seen this happen when using ABCMeta
so it could be something specific to that module, anyone know what might be happening?
In [1]: from abc import ABCMeta
In [2]: class test(metaclass=ABCMeta):
...: pass
...:
In [3]: newclass = type('newclass', (test,), {})
In [4]: newclass.__module__
Out[4]: 'abc'
当我以更标准的方式定义子类时,就会发生我想要的行为:
The behavior I want happens when I define the subclass in the more standard way:
In [5]: class subtest(test):
...: pass
...:
In [6]: subtest.__module__
Out[6]: '__main__'
有人可以解释为什么会这样吗,以及如何使用type
创建一个继承了正确的__module__
属性(例如__module__=='__main__'
)的新子类?
Can someone explain why this is the case and how you could, using type
, create a new subclass with the correct __module__
attribute inherited (e.g. __module__=='__main__'
)?
推荐答案
如果传递给type.__new__
的映射中没有__module__
键,则type.__new__
根据调用type.__new__
,在顶部Python堆栈框架的全局变量.
If no __module__
key is present in the mapping passed to type.__new__
, type.__new__
determines __module__
based on the module where the call to type.__new__
occurs, by looking for __name__
in the globals of the top Python stack frame.
运行newclass = type('newclass', (test,), {})
时,type
构造函数将委托给abc.ABCMeta
,
When you run newclass = type('newclass', (test,), {})
, the type
constructor delegates to abc.ABCMeta
, which then calls type.__new__
from inside the abc
module, so type
thinks that __module__
should probably be abc
.
当您编写类语句时
class subtest(test):
pass
class语句的已编译字节码自动包含一个__module__ = __name__
赋值,该赋值使用当前模块的__name__
而不是abc.__name__
.
The compiled bytecode for the class statement automatically includes a __module__ = __name__
assignment, which uses the current module's __name__
instead of abc.__name__
.
如果要控制直接调用type
创建的类的__module__
值,则可以在原始映射中设置键,或者在创建后将其分配给该类的__module__
:
If you want to control the value of __module__
for a class created by calling type
directly, you can set the key in the original mapping, or assign to the class's __module__
after creation:
newclass = type('newclass', (test,), {'__module__': __name__})
# or
newclass = type('newclass', (test,), {})
newclass.__module__ = __name__
这篇关于使用type()手动创建新类时,将子类__module__设置为元类模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!