问题
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