子类_​​_module__在手动创建类型为(

时间:2018-03-23 19:56:29

标签: python python-3.x metaprogramming metaclass

在下面的示例中,新创建的子类最终是元类__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__')?

1 个答案:

答案 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模块中委派给abcwhich 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__