En Python, dado un módulo X y una clase Y, ¿cómo puedo iterar o generar una lista de todas las subclases de Y que existen en el módulo X?Iterar sobre las subclases de una clase dada en un módulo dado
Respuesta
Ésta es una forma de hacerlo:
import inspect
def get_subclasses(mod, cls):
"""Yield the classes in module ``mod`` that inherit from ``cls``"""
for name, obj in inspect.getmembers(mod):
if hasattr(obj, "__bases__") and cls in obj.__bases__:
yield obj
Dado el módulo de foo.py
class foo(object): pass
class bar(foo): pass
class baz(foo): pass
class grar(Exception): pass
def find_subclasses(module, clazz):
for name in dir(module):
o = getattr(module, name)
try:
if issubclass(o, clazz):
yield name, o
except TypeError: pass
>>> import foo
>>> list(foo.find_subclasses(foo, foo.foo))
[('bar', <class 'foo.bar'>), ('baz', <class 'foo.baz'>), ('foo', <class 'foo.foo'>)]
>>> list(foo.find_subclasses(foo, object))
[('bar', <class 'foo.bar'>), ('baz', <class 'foo.baz'>), ('foo', <class 'foo.foo'>), ('grar', <class 'foo.grar'>)]
>>> list(foo.find_subclasses(foo, Exception))
[('grar', <class 'foo.grar'>)]
¿Puedo sugerir que ninguna de las respuestas de Chris AtLee y zacherates cumplir con los requisitos? creo que esta modificación a zacerates respuesta es mejor:
def find_subclasses(module, clazz):
for name in dir(module):
o = getattr(module, name)
try:
if (o != clazz) and issubclass(o, clazz):
yield name, o
except TypeError: pass
La razón estoy de acuerdo con las respuestas dadas es que el primero no produce las clases que son una subclase distante de la clase dada, y el segundo incluye el dado clase.
Aunque la sugerencia de Quamrana funciona bien, hay un par de posibles mejoras que me gustaría sugerir para hacerlo más pitónico. Confían en usar el módulo de inspección de la biblioteca estándar.
- Usted puede evitar la llamada getattr utilizando
inspect.getmembers()
- El try/catch se pueden evitar mediante el uso de
inspect.isclass()
Con ellos, se puede reducir todo a una lista única de comprensión si como:
def find_subclasses(module, clazz):
return [
cls
for name, cls in inspect.getmembers(module)
if inspect.isclass(cls) and issubclass(cls, clazz)
]
Funciona muy bien, pero mi respuesta también devuelve la clase base (la que envío con clazz), ¿alguna idea? – fredrik
Fredrik, resulta que issubclass (Foo, Foo) es Verdadero. Sin embargo, una solución fácil. agregar "y no cls es clazz" a la lista de comprensión – runeh
-1: el código no funciona. corregir sería: 'cls para nombre, cls en inspeccionar.obtener miembros (módulo)' – tback
- 1. iterar sobre las propiedades de una clase php
- 2. cómo obtener todas las subclases de una clase en php
- 3. ¿Hay una función estándar para iterar sobre las clases base?
- 4. Registre una clase C++ para que luego una función pueda iterar sobre todas las clases registradas
- 5. Iterar las clases definidas en un módulo importado dinámicamente
- 6. Descubre las subclases de una clase determinada en Obj-C
- 7. ¿Cómo puedo iterar sobre las propiedades de un archivo?
- 8. iterar sobre una tupla
- 9. Cómo iterar sobre las caras en CGAL
- 10. HQL consulta sobre subclases
- 11. iterar sobre las filas/casillas de verificación en un RadGrid
- 12. perl: iterar sobre un typeglob
- 13. Iterar sobre las propiedades de JsonObject
- 14. ¿Es posible obtener todas las subclases de una clase?
- 15. ¿Cómo iterar sobre un TreeMap?
- 16. ¿Cómo iterar sobre una priority_queue?
- 17. Dado un módulo en pypi, ¿hay alguna manera de introspectar el módulo y mostrar todas las dependencias?
- 18. Cómo iterar sobre un hash en mustache.js
- 19. Iterar todas las teclas de un mapa
- 20. Como puedo iterar sobre las funciones Array.prototype
- 21. Python iterar sobre un diccionario
- 22. C++ :: Boost :: Regex Iterar sobre las subcompetencias
- 23. Iterar sobre una columna en PL/SQL
- 24. Java: Crear subclases de una clase genericised
- 25. C++: iterar sobre una lista de un tipo genérico
- 26. ¿Cómo iterar sobre una cadena en C?
- 27. iterar sobre (tema, otros) en una lista
- 28. ¿Cómo iterar sobre un hash en Ruby?
- 29. ¿Cómo puedo iterar sobre los miembros de la clase?
- 30. Subclases de una clase que implementa una interfaz genérica
Mi solución no devolverá las clases que no sean descendientes directas de 'cls'. La solución de quamrana a continuación encontrará cualquier clase que tenga 'cls' en algún lugar de su ascendencia. –