Widziałem wiele przykładów ludzi wydobywających wszystkie klasy z modułu, zwykle coś takiego:
# foo.py
class Foo:
pass
# test.py
import inspect
import foo
for name, obj in inspect.getmembers(foo):
if inspect.isclass(obj):
print obj
Niesamowite.
Ale nie mogę się dowiedzieć, jak uzyskać wszystkie klasy z bieżącego modułu.
# 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()
To prawdopodobnie coś naprawdę oczywistego, ale nic nie znalazłem. Czy ktoś może mi pomóc?
python
reflection
inspect
Mccclean
źródło
źródło
"class"
? Dlaczego to nie zadziała?Odpowiedzi:
Spróbuj tego:
W twoim kontekście:
A nawet lepiej:
Ponieważ
inspect.getmembers()
wymaga orzeczenia.źródło
from optparse import OptionParser
), Moduły te zostaną uwzględnione na liście drukowania. Jak mogę tego uniknąć?inspect.getmembers(sys.modules[__name__], lambda member: member.__module__ == __name__ and isnpect.isclass)
dict(inspect.getmembers(sys.modules[__name__])) == globals()
jest zawszeTrue
, więc dlaczego import?inspect.getmembers(sys.modules[__name__], lambda member: inspect.isclass(member) and member.__module__ == __name__
isclass
.Co powiesz na
?
źródło
isinstance(obj, types.ClassType)
pudb
uruchamianie programu w ten sposób, powodują, że kod ulega przypadkowemu uszkodzeniusys.modules
podczas debugowania.globals()
wydaje się trochę brzydka, ale wydaje się być bardziej niezawodna.Nie wiem, czy istnieje „właściwy” sposób, aby to zrobić, ale Twój fragment
import foo
kodu jest na dobrej drodze: po prostu dodaj do foo.py, zróbinspect.getmembers(foo)
i powinien działać dobrze.źródło
Byłem w stanie uzyskać wszystko, czego potrzebowałem z
dir
wbudowanego plusgetattr
.Chociaż wygląda jak sierść:
źródło
Zauważ, że moduł przeglądarki klasy Python w stdlib wykorzystuje statyczną analizę źródła, więc działa tylko dla modułów, które są wspierane przez prawdziwy
.py
plik.źródło
Jeśli chcesz mieć wszystkie klasy należące do bieżącego modułu, możesz użyć tego:
Jeśli użyjesz odpowiedzi Nadii i importujesz inne klasy do swojego modułu, klasy te również zostaną zaimportowane.
Właśnie dlatego
member.__module__ == __name__
jest dodawany do predykatu używanego nais_class_member
. Ta instrukcja sprawdza, czy klasa naprawdę należy do modułu.Predykat to funkcja (wywoływalna), która zwraca wartość logiczną.
źródło
Kolejne rozwiązanie, które działa w Pythonie 2 i 3:
źródło
To jest linia, której używam, aby uzyskać wszystkie klasy, które zostały zdefiniowane w bieżącym module (tj. Nie są importowane). Według PEP-8 jest trochę długi, ale możesz go zmienić według własnego uznania.
To daje listę nazw klas. Jeśli chcesz same obiekty klasy, po prostu zachowaj obj zamiast tego.
To było bardziej przydatne z mojego doświadczenia.
źródło
źródło
Myślę, że możesz zrobić coś takiego.
jeśli potrzebujesz własnych zajęć
źródło
Często piszę narzędzia wiersza poleceń, w których pierwszy argument ma odnosić się do jednej z wielu różnych klas. Na przykład
./something.py feature command —-arguments
, gdzieFeature
jest klasa icommand
metoda dla tej klasy. Oto podstawowa klasa, która ułatwia to.Zakłada się, że ta klasa bazowa znajduje się w katalogu obok wszystkich jego podklas. Możesz wtedy zadzwonić,
ArgBaseClass(foo = bar).load_subclasses()
co zwróci słownik. Na przykład, jeśli katalog wygląda następująco:Zakładając , że
feature.py
implementujeclass Feature(ArgBaseClass)
, wówczas powyższe wywołanieload_subclasses
zwróci{ 'feature' : <Feature object> }
. To samokwargs
(foo = bar
) zostanie przekazane doFeature
klasy.źródło