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

て烟熏妆下的殇ゞ 提交于 2019-12-01 19:28:59

问题


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__'

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__')?


回答1:


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.

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.

When you write the class statement

class subtest(test):
    pass

The compiled bytecode for the class statement automatically includes a __module__ = __name__ assignment, which uses the current module's __name__ instead of abc.__name__.

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__


来源:https://stackoverflow.com/questions/49457441/subclass-module-set-to-metaclass-module-when-manually-creating-new-class-wit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!