subclase __module__ establecido en módulo de metaclase cuando se crea manualmente una nueva clase con type ()

En el siguiente ejemplo, la subclase recién creada termina siendo la metaclase __module__ lugar del módulo de las clases primarias. Solo he visto que esto sucede cuando uso ABCMeta por lo que podría ser algo específico de ese módulo, ¿alguien sabe qué podría estar pasando?

 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' 

El comportamiento que quiero ocurre cuando defino la subclase de la manera más estándar:

 In [5]: class subtest(test): ...: pass ...: In [6]: subtest.__module__ Out[6]: '__main__' 

¿Alguien puede explicar por qué este es el caso y cómo podría, utilizando type , crear una nueva subclase con el atributo correcto de __module__ heredado (por ejemplo, __module__=='__main__' )?

Related of "subclase __module__ establecido en módulo de metaclase cuando se crea manualmente una nueva clase con type ()"

Si no hay __module__ clave __module__ presente en la asignación pasada al type.__new__ , type.__new__ determina __module__ basándose en el módulo donde se produce la llamada al type.__new__ , buscando __name__ en los globales del marco de stack Python superior .

Cuando ejecutas newclass = type('newclass', (test,), {}) , el constructor de type delega en abc.ABCMeta , que luego llama a type.__new__ desde dentro del módulo abc , por lo que type que __module__ probablemente debería ser abc .

Cuando escribes la statement de la clase

 class subtest(test): pass 

El bytecode comstackdo para la statement de clase incluye automáticamente una asignación __module__ = __name__ , que utiliza el __name__ del módulo actual en lugar de abc.__name__ .

Si desea controlar el valor de __module__ para una clase creada llamando directamente al type , puede configurar la clave en la asignación original, o asignarla al __module__ la clase después de la creación:

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