He visto muchos ejemplos de personas que extraen todas las clases de un módulo, generalmente algo así como:
# foo.py
class Foo:
pass
# test.py
import inspect
import foo
for name, obj in inspect.getmembers(foo):
if inspect.isclass(obj):
print obj
Increíble.
Pero no puedo descubrir cómo obtener todas las clases del módulo actual .
# foo.py
import inspect
class Foo:
pass
def print_classes():
for name, obj in inspect.getmembers(???): # what do I do here?
if inspect.isclass(obj):
print obj
# test.py
import foo
foo.print_classes()
Esto es probablemente algo realmente obvio, pero no he podido encontrar nada. ¿Puede alguien ayudarme?
python
reflection
inspect
mcccclean
fuente
fuente
"class"
? ¿Por qué eso no funciona?Respuestas:
Prueba esto:
En tu contexto:
Y aún mejor:
Porque
inspect.getmembers()
toma un predicado.fuente
from optparse import OptionParser
) esos módulos se incluyen en la lista de impresión. ¿Cómo podría evitar eso?inspect.getmembers(sys.modules[__name__], lambda member: member.__module__ == __name__ and isnpect.isclass)
dict(inspect.getmembers(sys.modules[__name__])) == globals()
siempre esTrue
así, ¿por qué las importaciones?inspect.getmembers(sys.modules[__name__], lambda member: inspect.isclass(member) and member.__module__ == __name__
isclass
.Qué pasa
?
fuente
isinstance(obj, types.ClassType)
pudb
ejecutar su programa de esta manera, lo que da como resultado que el código sesys.modules
rompa al azar mientras lo depura.globals()
parece un poco feo, pero parece ser mucho más confiable.No sé si hay una forma 'adecuada' de hacerlo, pero su fragmento está en el camino correcto: solo agregue
import foo
a foo.py, doinspect.getmembers(foo)
, y debería funcionar bien.fuente
Pude obtener todo lo que necesitaba del
dir
plus incorporadogetattr
.Sin embargo, parece una bola de pelo:
fuente
Tenga en cuenta que el módulo de navegador de clase Python de stdlib utiliza análisis de fuente estática, por lo que solo funciona para módulos respaldados por un
.py
archivo real .fuente
Si desea tener todas las clases, que pertenecen al módulo actual, puede usar esto:
Si usa la respuesta de Nadia y estaba importando otras clases en su módulo, esas clases también se importarán.
Por eso
member.__module__ == __name__
se agrega al predicado utilizado enis_class_member
. Esta declaración comprueba que la clase realmente pertenece al módulo.Un predicado es una función (invocable), que devuelve un valor booleano.
fuente
Otra solución que funciona en Python 2 y 3:
fuente
Esta es la línea que uso para obtener todas las clases que se han definido en el módulo actual (es decir, no importado). Según PEP-8, es un poco largo, pero puede cambiarlo como mejor le parezca.
Esto le da una lista de los nombres de clase. Si desea que los objetos de la clase se mantengan obj en su lugar.
Esto ha sido más útil en mi experiencia.
fuente
fuente
Creo que puedes hacer algo como esto.
si necesitas clases propias
fuente
Con frecuencia me encuentro escribiendo utilidades de línea de comandos en donde el primer argumento está destinado a referirse a una de muchas clases diferentes. Por ejemplo
./something.py feature command —-arguments
, dondeFeature
es una clase ycommand
es un método en esa clase. Aquí hay una clase base que facilita esto.Se supone que esta clase base reside en un directorio junto con todas sus subclases. Luego puede llamar,
ArgBaseClass(foo = bar).load_subclasses()
lo que devolverá un diccionario. Por ejemplo, si el directorio se ve así:Suponiendo
feature.py
implementosclass Feature(ArgBaseClass)
, entonces la invocación anterior deload_subclasses
regresará{ 'feature' : <Feature object> }
. Lo mismokwargs
(foo = bar
) se pasará a laFeature
clase.fuente