Ich habe viele Beispiele von Leuten gesehen, die alle Klassen aus einem Modul extrahiert haben, normalerweise so etwas wie:
# foo.py
class Foo:
pass
# test.py
import inspect
import foo
for name, obj in inspect.getmembers(foo):
if inspect.isclass(obj):
print obj
Genial.
Ich kann jedoch nicht herausfinden, wie alle Klassen aus dem aktuellen Modul abgerufen werden können.
# 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()
Dies ist wahrscheinlich etwas wirklich Offensichtliches, aber ich konnte nichts finden. Kann mir jemand helfen?
python
reflection
inspect
mcccclean
quelle
quelle
"class"
? Warum funktioniert das nicht?Antworten:
Versuche dies:
In Ihrem Kontext:
Und noch besser:
Weil
inspect.getmembers()
ein Prädikat braucht.quelle
from optparse import OptionParser
) importiere, werden diese Module in die Druckliste aufgenommen. Wie könnte ich das vermeiden?inspect.getmembers(sys.modules[__name__], lambda member: member.__module__ == __name__ and isnpect.isclass)
dict(inspect.getmembers(sys.modules[__name__])) == globals()
ist immerTrue
, warum also die Importe?inspect.getmembers(sys.modules[__name__], lambda member: inspect.isclass(member) and member.__module__ == __name__
isclass
.Wie wäre es mit
?
quelle
isinstance(obj, types.ClassType)
pudb
Ihr Programm auf diese Weise ausführen, was dazu führt, dass Codesys.modules
beim Debuggen zufällig unterbrochen wird.globals()
scheint ein bisschen hässlich, aber es scheint viel zuverlässiger zu sein.Ich weiß nicht, ob es einen "richtigen" Weg gibt, aber Ihr Snippet ist auf dem richtigen Weg:
import foo
Fügen Sie einfach foo.py hinzu, tun Sieinspect.getmembers(foo)
, und es sollte gut funktionieren.quelle
Mit dem
dir
eingebauten Plus konnte ich alles bekommen, was ich brauchtegetattr
.Es sieht jedoch aus wie ein Haarball:
quelle
Beachten Sie, dass das Python-Klassenbrowsermodul der stdlib eine statische Quellenanalyse verwendet, sodass es nur für Module funktioniert, die von einer realen
.py
Datei unterstützt werden.quelle
Wenn Sie alle Klassen haben möchten, die zum aktuellen Modul gehören, können Sie Folgendes verwenden:
Wenn Sie Nadias Antwort verwenden und andere Klassen in Ihr Modul importiert haben, werden diese Klassen ebenfalls importiert.
Deshalb
member.__module__ == __name__
wird dem verwendeten Prädikat hinzugefügtis_class_member
. Diese Anweisung überprüft, ob die Klasse wirklich zum Modul gehört.Ein Prädikat ist eine Funktion (aufrufbar), die einen booleschen Wert zurückgibt.
quelle
Eine andere Lösung, die in Python 2 und 3 funktioniert:
quelle
Dies ist die Zeile, mit der ich alle Klassen abrufe, die im aktuellen Modul definiert wurden (dh nicht importiert wurden). Laut PEP-8 ist es etwas lang, aber Sie können es nach Belieben ändern.
Dies gibt Ihnen eine Liste der Klassennamen. Wenn Sie die Klassenobjekte selbst möchten, behalten Sie stattdessen obj bei.
Dies war meiner Erfahrung nach nützlicher.
quelle
quelle
Ich denke, dass Sie so etwas tun können.
wenn Sie eigene Klassen benötigen
quelle
Ich schreibe häufig Befehlszeilenprogramme, bei denen sich das erste Argument auf eine von vielen verschiedenen Klassen beziehen soll. Zum Beispiel
./something.py feature command —-arguments
, woFeature
ist eine Klasse undcommand
ist eine Methode für diese Klasse. Hier ist eine Basisklasse, die dies einfach macht.Es wird davon ausgegangen, dass sich diese Basisklasse neben allen Unterklassen in einem Verzeichnis befindet. Sie können dann anrufen,
ArgBaseClass(foo = bar).load_subclasses()
wodurch ein Wörterbuch zurückgegeben wird. Wenn das Verzeichnis beispielsweise so aussieht:Unter der Annahme von
feature.py
Implementierungenclass Feature(ArgBaseClass)
wird der obige Aufruf vonload_subclasses
zurückgegeben{ 'feature' : <Feature object> }
. Das gleichekwargs
(foo = bar
) wird an dieFeature
Klasse übergeben.quelle