使用 type() 手动创建新的 class 时,subclass __module__ 设置为 metaclass 模块

subclass __module__ set to metaclass module when manually creating new class with type()

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

如果传递给 type.__new__ 的映射中不存在 __module__ 键,type.__new__ 根据调用 type.__new__ 的模块确定 __module__发生,by looking for __name__ in the globals of the top Python stack frame.

当您 运行 newclass = type('newclass', (test,), {}) 时,type 构造函数从 abc 模块内部委托给 abc.ABCMetawhich then calls type.__new__,因此 type 认为 __module__ 应该是 abc.

当你编写 class 语句时

class subtest(test):
    pass

class语句的编译字节码自动包含一个__module__ = __name__赋值,它使用当前模块的__name__而不是abc.__name__

直接调用type创建的class如果想控制__module__的值,可以在原映射中设置key,或者赋值给class的__module__创建后:

newclass = type('newclass', (test,), {'__module__': __name__})

# or

newclass = type('newclass', (test,), {})
newclass.__module__ = __name__