Wie kann ich in Python, wenn ein Modul X und eine Klasse Y gegeben sind, eine Liste aller Unterklassen von Y, die in Modul X existieren, iterieren oder generieren?Iterate über Unterklassen einer gegebenen Klasse in einem gegebenen Modul
Antwort
Hier ist eine Möglichkeit, es zu tun:
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
Da das Modul 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'>)]
Kann ich vorschlagen, dass keine der Antworten von Chris AtLee und zacherates die Anforderungen erfüllen? Ich denke, diese Änderung zu zacerates Antwort ist besser:
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
Der Grund, warum ich mit den Antworten andere Meinung ist, dass die erste nicht-Klassen produziert, die eine entfernte Unterklasse der gegebenen Klasse sind, und der zweite enthält die gegebenen Klasse.
Obwohl Quamranas Vorschlag gut funktioniert, gibt es ein paar mögliche Verbesserungen, die ich vorschlagen möchte, um es pythonischer zu machen. Sie verwenden das inspect-Modul aus der Standardbibliothek. wenn Sie
- Sie können die getattr Anruf vermeiden, indem
inspect.getmembers()
- Der try/catch verwenden, können mithilfe von
inspect.isclass()
mit denen vermieden werden kann, können Sie das Ganze auf eine einzige Liste Verständnis reduzieren wie:
def find_subclasses(module, clazz):
return [
cls
for name, cls in inspect.getmembers(module)
if inspect.isclass(cls) and issubclass(cls, clazz)
]
Funktioniert gut, aber meine Antwort gibt auch die Basisklasse zurück (die ich mit cazz einschicke), irgendeine Idee? – fredrik
Fredrik, stellt sich heraus, issubclass (Foo, Foo) ist True. Einfache Lösung, obwohl. add "und nicht cls ist clazz" zum Listenverständnis – runeh
-1: Code funktioniert nicht. richtig wäre es: 'cls für name, cls in inspect.getmembers (modul)' – tback
- 1. Unterklassen einer gegebenen Klasse in Obj-C entdecken
- 2. Wie aus einem gegebenen Zufallsgenerator
- 3. Aktualisieren einer gegebenen SESSION-Info
- 4. Open Text von einem gegebenen Offset (Java)
- 5. Python - Zähle Wörter in einem gegebenen Text
- 6. einen Zyklus in einem gegebenen Array Detecting
- 7. Größter Primfaktor einer gegebenen Zahl in Python
- 8. Wie finden Sie alle Permutationen eines gegebenen Wortes in einem gegebenen Text?
- 9. Merging gegebenen Objekte
- 10. Speichern Plot mit einem gegebenen Seitenverhältnis
- 11. Gut alle Zeichenkombinationen mit einer gegebenen Länge
- 12. Finde alle Subsequenzen einer gegebenen Zeichenkette
- 13. alle Beziehungen finden mit einem gegebenen Knoten
- 14. in PHP für gegebenen Bereich
- 15. Prolog: Erzeugen aller Möglichkeiten einer Liste mit einem gegebenen Muster
- 16. Entfernen aller Zeichen aus einer gegebenen Zeichenfolge
- 17. Lesen einer Binärdatei mit Numpy fromfile und einem gegebenen Offset
- 18. Komplementärfarbe/Gegenfarbe einer gegebenen Farbe herausfinden
- 19. Finden Sie alle Submatrizen einer gegebenen Matrix
- 20. Count verschiedene „Räume“ zwischen einer gegebenen Anzahl
- 21. Berechnen CIDR von einer gegebenen Netzmaske - Java
- 22. Javascript Zugangsparameter außerhalb einer gegebenen Funktion
- 23. jQuery DataTables - Seite einer gegebenen Zeile
- 24. Wie bekomme ich das Array von der gegebenen Klasse Item?
- 25. Subtrahiere eine Sekunde von einer gegebenen Zeit
- 26. Get label einer gegebenen dbpedia-Ressource
- 27. Get Eigenschaften einer gegebenen DBpedia Kategorie
- 28. Java: Iteration von gegebenen Daten
- 29. lesen Textdatei mit gegebenen Informationen
- 30. Linie mit gegebenen Punkten verlängern
Meine Lösung wird keine Klassen zurückgeben, die keine direkten Nachkommen von 'cls' sind. Die Lösung von Quamrana unten findet jede Klasse, die irgendwo in ihrer Herkunft "cls" hat. –