在下面的示例中,新创建的子类最终是元类__module__
而不是父类的模块。我只是在使用ABCMeta
时才发现这种情况,所以它可能是该模块的特定内容,任何人都知道可能会发生什么?
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'
当我以更标准的方式定义子类时,我想要的行为发生了:
In [5]: class subtest(test):
...: pass
...:
In [6]: subtest.__module__
Out[6]: '__main__'
有人可以解释为什么会出现这种情况,并且如何使用type
创建一个新的子类,并继承正确的__module__
属性(例如__module__=='__main__'
)?
答案 0 :(得分:5)
如果传递给__module__
的映射中没有type.__new__
密钥,则type.__new__
会根据调用__module__
的模块确定type.__new__
, by looking for __name__
in the globals of the top Python stack frame
当您运行newclass = type('newclass', (test,), {})
时,type
构造函数会从abc.ABCMeta
模块中委派给abc
,which then calls type.__new__
,因此type
认为__module__
应该是abc
。
编写类语句时
class subtest(test):
pass
类语句的已编译字节码自动包含__module__ = __name__
赋值,该赋值使用当前模块的__name__
而不是abc.__name__
。
如果要控制通过直接调用__module__
创建的类的type
值,可以在原始映射中设置键,或者在之后分配给类__module__
创建:
newclass = type('newclass', (test,), {'__module__': __name__})
# or
newclass = type('newclass', (test,), {})
newclass.__module__ = __name__