使用type()手动创建新类时,将子类__module__设置为元类模块 [英] subclass __module__ set to metaclass module when manually creating new class with type()

查看:113
本文介绍了使用type()手动创建新类时,将子类__module__设置为元类模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆