子类_​​_module__在手动创建类型为()的新类时设置为元类模块

Dan*_*Liu 4 python metaprogramming metaclass python-3.x

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

当我以更标准的方式定义子类时,我想要的行为发生:

In [5]: class subtest(test):
   ...:     pass
   ...: 

In [6]: subtest.__module__
Out[6]: '__main__'
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么会这样,并且如何使用type,创建一个具有正确__module__属性的新子类(例如__module__=='__main__')?

use*_*ica 5

如果没有__module__键存在于传递到所述映射type.__new__,type.__new__确定__module__基于其中给该呼叫的模块上type.__new__发生时,通过寻找__name__在顶部的Python堆栈帧的全局.

当你运行时newclass = type('newclass', (test,), {}),type构造函数委托给abc.ABCMeta,然后type.__new__abc模块内部调用,所以type认为__module__应该是abc.

当你编写类语句时

class subtest(test):
    pass
Run Code Online (Sandbox Code Playgroud)

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

如果要控制__module__通过type直接调用创建的类的值,可以在原始映射中设置键,或者__module__在创建后分配给类:

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

# or

newclass = type('newclass', (test,), {})
newclass.__module__ = __name__
Run Code Online (Sandbox Code Playgroud)