¿Cómo se obtienen todas las clases definidas en un módulo pero no importadas?


Ya he visto la siguiente pregunta pero no me lleva a donde quiero: ¿Cómo puedo obtener una lista de todas las clases dentro del módulo actual en Python?

En particular, no quiero clases que se importen, por ejemplo, si tuviera el siguiente módulo:

from my.namespace import MyBaseClass
from somewhere.else import SomeOtherClass

class NewClass(MyBaseClass):
    pass

class AnotherClass(MyBaseClass):
    pass

class YetAnotherClass(MyBaseClass):
    pass

Si utilizo clsmembers = inspect.getmembers(sys.modules[__name__], inspect.isclass) como sugiere la respuesta aceptada en la pregunta vinculada, devolvería MyBaseClass y SomeOtherClass además de los 3 definidos en este módulo.

¿Cómo puedo obtener solo NewClass, AnotherClass y YetAnotherClass?

Author: Community, 2011-04-02

5 answers

Inspeccione el atributo __module__ de la clase para averiguar en qué módulo se definió.

 24
Author: Ignacio Vazquez-Abrams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-02 01:54:38

Me disculpo por responder a una pregunta tan antigua, pero no me sentí cómodo usando el módulo inspect para esta solución. Leí en algún lugar que no era seguro usar en producción.

Inicializar todas las clases de un módulo en objetos sin nombre en una lista

Ver Antonis Christofides comentario a la respuesta 1.

Obtuve la respuesta para probar si un objeto es una clase de Cómo comprobar si una variable es una clase o no?

Así que esto es mi solución sin inspección

def classesinmodule(module):
    md = module.__dict__
    return [
        md[c] for c in md if (
            isinstance(md[c], type) and md[c].__module__ == module.__name__
        )
    ]

classesinmodule(modulename)
 12
Author: piRSquared,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:25:48

Es posible que también desee considerar el uso del módulo "Python class browser" en la biblioteca estándar: http://docs.python.org/library/pyclbr.html

Dado que en realidad no ejecuta el módulo en cuestión (en su lugar realiza una inspección de código fuente ingenua), hay algunas técnicas específicas que no entiende correctamente, pero para todas las definiciones de clase "normales", las describirá con precisión.

 7
Author: ncoghlan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-02 03:14:06

Usé lo siguiente:

# Predicate to make sure the classes only come from the module in question
def pred(c):
    return inspect.isclass(c) and c.__module__ == pred.__module__
# fetch all members of module __name__ matching 'pred'
classes = inspect.getmembers(sys.modules[__name__], pred)

No quería escribir el nombre del módulo actual en

 7
Author: rmc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-11 11:58:41
from pyclbr import readmodule

clsmembers = readmodule(__name__).items()
 2
Author: drruggeri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-19 03:48:48