Chcę uzyskać atrybuty klasy, powiedz:
class MyClass():
a = "12"
b = "34"
def myfunc(self):
return self.a
using MyClass.__dict__
daje mi listę atrybutów i funkcji, a nawet funkcji takich jak __module__
i __doc__
. While MyClass().__dict__
daje mi pusty komunikat, chyba że jawnie ustawię wartość atrybutu tej instancji.
Chcę tylko atrybutów, w powyższym przykładzie byłyby to: a
ib
python
python-2.7
class
attributes
Mohamed Khamis
źródło
źródło
Odpowiedzi:
Wypróbuj moduł inspekcji .
getmembers
a różne testy powinny być pomocne.EDYTOWAĆ:
Na przykład,
Teraz, te specjalne metody i atrybuty działają mi na nerwy - można sobie z nimi radzić na wiele sposobów, z których najłatwiejszym jest filtrowanie na podstawie nazwy.
... a bardziej skomplikowane może obejmować sprawdzanie nazw atrybutów specjalnych, a nawet metaklasy;)
źródło
attributes = inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a)))
print [a[0] for a in attributes if '_' not in a[0]]
like_this
! Pozwoli to również uniknąć atrybutów „prywatnych”, które mogłeś zrobić celowo.inspect.getmembers(MyClass, ...
,MyClass
może być zastąpiony przez klasy lub obiektu, a jeśli potrzebujesz listę wartości swoich przedmiotów, należy zastąpićMyClass
przez zmienną obiektu (lubself
jeśli umieścisz to wyrażenie wdef __repr__()
metodzie takiej jak ja).i = inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a))); z = [_[1] for _ in i if _[0] in '__dict__'][0]
a potem jest tylko kwestia uzyskania kluczy z z.źródło
if not i.startswith('_')
zamiastif i[:1] != '_'
?.__dict__.keys()
nie będziemy uwzględniać atrybutów od rodzica.myfunc
jest atrybutemMyClass
. Tak to się dzieje, gdy biegasz:Szuka atrybutu w
myinstance
namedmyfunc
, nie znajduje go, widzi, żemyinstance
jest to instancjaMyClass
i tam go szuka.Tak więc pełna lista atrybutów dla
MyClass
:(Zwróć uwagę, że używam dir tylko jako szybkiego i łatwego sposobu na listę członków klasy: powinien być używany tylko w sposób eksploracyjny, a nie w kodzie produkcyjnym)
Jeśli chcesz tylko poszczególne atrybuty, musisz filtrować tej listy przy użyciu pewnych kryteriów, ponieważ
__doc__
,__module__
imyfunc
nie są w żaden szczególny sposób, są one atrybuty dokładnie w ten sam sposób,a
ib
są.Nigdy nie korzystałem z modułu inspect, o którym wspominali Matt i Borealid, ale z krótkiego linku wygląda na to, że zawiera testy, które pomogą ci to zrobić, ale musisz napisać własną funkcję predykatu, ponieważ wydaje się, że chcesz to z grubsza atrybuty, które nie przechodzą
isroutine
testu i nie zaczynają się ani nie kończą dwoma podkreśleniami.Uwaga: używając
class MyClass():
w Pythonie 2.7 używasz dziko przestarzałych klas w starym stylu. O ile nie robisz tego celowo w celu zapewnienia zgodności z bardzo starymi bibliotekami, powinieneś zamiast tego zdefiniować swoją klasę jakoclass MyClass(object):
. W Pythonie 3 nie ma klas „w starym stylu” i to zachowanie jest domyślne. Jednak użycie klas newstyle pozwoli ci uzyskać znacznie więcej automatycznie definiowanych atrybutów:źródło
dir()
: „ Ponieważ dir () jest dostarczany przede wszystkim jako wygoda w użyciu w interaktywnym znaku zachęty, bardziej stara się dostarczyć interesujący zestaw nazw, niż stara się dostarczyć rygorystycznie lub konsekwentnie zdefiniowany zestaw nazw , a jego szczegółowy zachowanie może się zmieniać w różnych wersjach . ”(zobacz dokumentacjędir()
).Pobieranie samych atrybutów instancji jest łatwe.
Ale uzyskanie również atrybutów klas bez funkcji jest nieco trudniejsze.
Tylko atrybuty instancji
Jeśli chcesz tylko wyświetlić atrybuty instancji, po prostu użyj
for attribute, value in my_instance
.__dict__
.items()
Atrybuty instancji i klasy
Aby uzyskać również atrybuty klasy bez funkcji, sztuczka polega na użyciu
callable()
.Ale statyczne metody są nie zawsze
callable
!Dlatego zamiast używać
callable(value)
usecallable
(getattr
(MyClass, attribute))
Przykład
Uwaga:
print_class_attributes()
powinno być, ale nie w tym głupim i prostym przykładzie.@staticmethod
Wynik dla python2
Ten sam wynik dla python3
źródło
MyClass().__class__.__dict__
Jednak „właściwym” było to zrobić za pośrednictwem modułu inspekcji .
źródło
MyClass().__class__.__dict__
==MyClass.__dict__
MyClass().__class__.__dict__ != MyClass().__dict__
, ale jaka nie zawiera nawiasów po prawej stronie, w przypadku których ma racjęNa przykład MyClass, takie jak
używać
type(mc)
zamiastMyClass
w zrozumieniu listy. Jeśli jednak dynamicznie dodaje atrybut domc
, na przykładmc.c = "42"
, atrybut nie pojawi się podczas stosowaniatype(mc)
w tej strategii. Podaje tylko atrybuty oryginalnej klasy.Aby uzyskać pełny słownik dla instancji klasy, musisz POŁĄCZYĆ słowniki
type(mc).__dict__
imc.__dict__
.źródło
Nie wiem, czy coś podobnego zostało już zrobione, czy nie, ale stworzyłem fajną funkcję wyszukiwania atrybutów za pomocą vars (). vars () tworzy słownik atrybutów klasy, przez którą przechodzisz.
Rozwijam całkiem sporą przygodę tekstową w Pythonie, moja klasa Player ma jak dotąd ponad 100 atrybutów. Używam tego do wyszukiwania określonych atrybutów, które muszę zobaczyć.
źródło
Myślę, że można to zrobić bez inspekcji.
Weź udział w następujących zajęciach:
Patrząc na członków wraz z ich typami:
... daje:
Aby wyświetlić tylko zmienne, wystarczy przefiltrować wyniki według typu, a nazwy nie zaczynają się od „__”. Na przykład
Otóż to.
Uwaga: jeśli używasz Pythona 3, przekonwertuj iteratory na listy.
Jeśli potrzebujesz bardziej niezawodnego sposobu, użyj inspect .
źródło
Python 2 i 3, bez importu, filtrując obiekty według ich adresów
Rozwiązania w skrócie:
Zwróć dict {nazwa_atrybutu: wartość_atrybutu} , obiekty przefiltrowane. to znaczy
{'a': 1, 'b': (2, 2), 'c': [3, 3]}
Lista zwrotów [nazwy_ atrybutów] , przefiltrowane obiekty. to znaczy
['a', 'b', 'c', 'd']
Lista zwrotów [atrybuty_wartości] , obiekty przefiltrowane. to znaczy
[1, (2, 2), [3, 3], {4: 4}]
Brak filtrowania obiektów
Usuwanie
if
warunku. Powrót{'a': 1, 'c': [3, 3], 'b': (2, 2), 'e': <function <lambda> at 0x7fc8a870fd70>, 'd': {4: 4}, 'f': <object object at 0x7fc8abe130e0>}
Rozwiązanie na długi czas
Dopóki realizacja domyślna
__repr__
nie jest przesłonięta naif
oświadczenie powróciTrue
jeśli reprezentacja szesnastkowy umieszczeniem w pamięcival
znajduje się w__repr__
ciąg powrotnej.Jeśli chodzi o domyślną implementację
__repr__
, ta odpowiedź może się przydać . W skrócie:Który zwraca ciąg, taki jak:
Lokalizację w pamięci każdego elementu uzyskuje się za pomocą
id()
metody.Python Docs mówi o id ():
Spróbuj sam
Wynik:
Uwaga :
Przetestowano w Pythonie
2.7.13
i Pythonie3.5.3
W Pythonie 2.x
.iteritems()
jest preferowany.items()
źródło
Niedawno musiałem wymyślić coś podobnego do tego pytania, więc chciałem opublikować kilka podstawowych informacji, które mogą być pomocne dla innych, którzy mają to samo w przyszłości.
Oto jak to działa w Pythonie (z https://docs.python.org/3.5/reference/datamodel.html#the-standard-type-hierarchy ):
MyClass
jest obiektem klasy,MyClass()
jest instancją obiektu klasy. Instancja zawiera__dict__
tylko atrybuty i metody specyficzne dla tej instancji (npself.somethings
.). Jeśli atrybut lub metoda jest częścią klasy, to należy do klasy__dict__
. Kiedy to zrobiszMyClass().__dict__
, instancjaMyClass
jest tworzona bez atrybutów ani metod poza atrybutami klasy, a zatem jest pusta__dict__
Więc jeśli powiesz
print(MyClass().b)
, Python najpierw sprawdza dyktando nowej instancjiMyClass().__dict__['b']
i nie znajdujeb
. Następnie sprawdza klasęMyClass.__dict__['b']
i znajdujeb
.Dlatego potrzebujesz
inspect
modułu do emulacji tego samego procesu wyszukiwania.źródło
Możesz użyć
dir()
w zrozumieniu list, aby uzyskać nazwy atrybutów:Użyj,
getattr()
aby uzyskać same atrybuty:źródło
Moje rozwiązanie, aby uzyskać wszystkie atrybuty (nie metody) klasy (jeśli klasa ma poprawnie napisany ciąg dokumentów, który ma jasno określone atrybuty):
Ten kawałek
cls.__dict__['__doc__']
wyodrębnia dokumentację klasy.źródło
Dlaczego musisz wymienić atrybuty? Wygląda na to, że semantycznie twoja klasa jest zbiorem. W takich przypadkach polecam użycie enum:
Wymień swoje atrybuty? Nie ma nic prostszego niż to:
źródło
Jeśli chcesz „pobrać” atrybut, istnieje bardzo prosta odpowiedź , która powinna być oczywista: getattr
Działa elegancko zarówno w Pythonie 2.7 i Pythonie 3.x.
Jeśli chcesz uzyskać listę tych elementów, nadal będziesz musiał użyć inspect.
źródło
dwie funkcje:
posługiwać się:
źródło
Oto, czego chcę.
Dane testowe
źródło
Wiem, że to było trzy lata temu, ale dla tych, którzy mają przyjść z tym pytaniem w przyszłości, dla mnie:
działa dobrze.
źródło
attribute
jest z góry.Możesz użyć
MyClass.__attrs__
. Po prostu podaje wszystkie atrybuty tej klasy. Nic więcej.źródło