Czy w Pythonie istnieje sposób na określenie, czy obiekt ma jakiś atrybut? Na przykład:
>>> a = SomeClass()
>>> a.someProperty = value
>>> a.property
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: SomeClass instance has no attribute 'property'
Jak rozpoznać, czy a
ma atrybut property
przed użyciem?
python
attributes
Lucas Gabriel Sánchez
źródło
źródło
import string hasattr(string, "lower")
hasattr
jest dokładnie taki sam, jak użycietry
/except AttributeError
: dokumentacja hasattr (w Pythonie 2.7) mówi, że używa wyjątków od chwytania rąk getattr.hasattr
niestety nie jest dokładnie taka sama jaktry: ... except AttributeError:
w Pythonie 2.x ponieważhasattr
będzie złapać wszystkie wyjątek . Proszę zobaczyć moją odpowiedź na przykład i proste obejście.hasattr
jest również najlepszym wyborem, jeśli rozumiesz, np.[a.property for a in list_of_as if hasattr(a, "property")]
Jak odpowiedział Jarret Hardie, załatwi sprawę
hasattr
. Chciałbym jednak dodać, że wielu członków społeczności Python zaleca strategię „łatwiej prosić o wybaczenie niż o pozwolenie” (EAFP) niż „patrzeć, zanim skoczysz” (LBYL). Zobacz te referencje:EAFP vs LBYL (jak do tej pory był trochę rozczarowany)
EAFP vs. LBYL @Code Like a Pythonista: Idiomatic Python
to znaczy:
... jest preferowany do:
źródło
try:
powinna być próba dostępu do atrybutu; nie ma też powodu, aby zawijać wykonaniedoStuff
. Nadal istnieje jednak pewien potencjał niejednoznaczności: jeśliproperty
jest obliczoną właściwością zamiast zwykłego atrybutu, jej implementacja może wzrosnąćAttributeError
wewnętrznie. Dlatego w prawie wszystkich rzeczywistych sytuacjach takich jak tagetattr
jest lepsza niżhasattr
złapanie lub złapanieAttributeError
.Możesz użyć
hasattr()
lub złapaćAttributeError
, ale jeśli naprawdę chcesz tylko wartość atrybutu z wartością domyślną, jeśli go nie ma, najlepszą opcją jest użyciegetattr()
:źródło
Myślę, że to, czego szukasz, to hasattr . Polecam jednak coś takiego, jeśli chcesz wykryć właściwości Pythona -
Wadą jest to, że
__get__
wychwytywane są również błędy atrybutów w kodzie właściwości .W przeciwnym razie zrób-
Dokumenty: http://docs.python.org/library/functions.html
Ostrzeżenie:
Powodem mojej rekomendacji jest to, że hasattr nie wykrywa właściwości.
Link: http://mail.python.org/pipermail/python-dev/2005-December/058498.html
źródło
hasattr
ogólnie dobrze wykrywa właściwości. Po prostu traktuje zgłoszenie wyjątku wproperty
funkcji -wrapped jako oznaczające, że taki atrybut nie istnieje; połączony post na liście mailingowej Pythona dotyczy właściwości, która podnosi wyjątek podczas próby uzyskania do niego dostępu. Dla wszystkich praktycznych celów wspomniany atrybut nie istnieje, ponieważ nigdy nie wygeneruje wartości. Ponadto,hasattr
tylko ogólnie tłumi wyjątki dotyczące Py 3.1 i wcześniejszych; w wersji 3.2+ tłumi tylko (zastępuje przezFalse
return)AttributeError
.Według pydoc, hasattr (obj, prop) po prostu wywołuje getattr (obj, prop) i wyłapuje wyjątki. Tak więc równie ważne jest zawinięcie dostępu do atrybutu instrukcją try i wyłapanie AttributeError, tak jak wcześniej należy użyć hasattr ().
źródło
hasattr
gdySomeClass
zastąpienia,__getattr__
ponieważhasattr
wychwytują wszystkie wyjątki w Pythonie 2.x, nie tylkoAttributeError
tak, jak można się spodziewać. Zostało to naprawione w Pythonie 3.2 - proszę zobaczyć moją inną odpowiedź na proste obejście.Chciałbym zasugerować, aby tego uniknąć:
Wspomniał o tym użytkownik @jpalecek: Jeśli coś
AttributeError
wystąpi w środkudoStuff()
, jesteś zgubiony.Może to podejście jest lepsze:
źródło
try: a.property
nie potrzeba lewej stronyW zależności od sytuacji możesz sprawdzić,
isinstance
jakiego rodzaju masz obiekt, a następnie użyć odpowiednich atrybutów. Wraz z wprowadzeniem abstrakcyjnych klas bazowych w Pythonie 2.6 / 3.0 to podejście stało się również znacznie bardziej wydajne (w zasadzie ABC pozwala na bardziej wyrafinowany sposób pisania kaczych znaków).Jedna sytuacja, w której byłoby to przydatne, miałaby miejsce, gdyby dwa różne obiekty miały atrybut o tej samej nazwie, ale o innym znaczeniu. Używanie tylko
hasattr
może prowadzić do dziwnych błędów.Dobrym przykładem jest rozróżnienie między iteratorami a iteratorami (patrz to pytanie). Te
__iter__
metody iteratora i iterable mieć taką samą nazwę, ale są semantycznie zupełnie inaczej!hasattr
Jest to więc bezużyteczne, aleisinstance
wraz z ABC zapewnia czyste rozwiązanie.Zgadzam się jednak, że w większości sytuacji
hasattr
podejście (opisane w innych odpowiedziach) jest najbardziej odpowiednim rozwiązaniem.źródło
Mam nadzieję, że oczekujesz hasattr (), ale staraj się unikać hasattr () i preferuj getattr (). getattr () jest szybszy niż hasattr ()
za pomocą hasattr ():
to samo tutaj używam getattr, aby uzyskać właściwość, jeśli nie ma właściwości, nie zwraca żadnych
źródło
EDYCJA : To podejście ma poważne ograniczenia. Powinien działać, jeśli obiekt jest iterowalny . Sprawdź komentarze poniżej.
Jeśli używasz Pythona w wersji 3.6 lub wyższej, tak jak ja, istnieje wygodna alternatywa, aby sprawdzić, czy obiekt ma określony atrybut:
Nie jestem jednak pewien, które z nich jest obecnie najlepsze. za pomocą
hasattr()
, za pomocągetattr()
lub za pomocąin
. Komentarze są mile widziane.źródło
in
słowo kluczowe działa w celu sprawdzenia typów iterowalnych. Na przykład'foo' in None
zgłasza błądTypeError: argument of type 'NoneType' is not iterable
. Rozwiązaniem jest sprawdzenie, czy typ jest iterowalny przed użyciemin
. Po skorygowaniu przypadków krawędzi, takich jak typ nie iterowalny, prawdopodobnie lepiej jest użyć,hasattr()
ponieważ jest zaprojektowany do obsługi przypadków krawędzi.dict
jako „lekkiego obiektu”, podobnego do projektowania obiektów JavaScript, ale większość normalnych klas nie obsługuje tego ogólnie (uzyskanie wariantu błędu wspomnianego przez @SethDifley) .Oto bardzo intuicyjne podejście:
źródło
Możesz sprawdzić, czy
object
zawiera atrybut, używająchasattr
wbudowanej metody.Na przykład, jeśli twój obiekt jest
a
i chcesz sprawdzić atrybutstuff
Sama sygnatura metody
hasattr(object, name) -> bool
oznacza, żeobject
ma atrybut, który jest przekazywany do drugiego argumentu,hasattr
niż daje wartość logicznąTrue
lubFalse
zależnie od obecnościname
atrybutu w obiekcie.źródło
Jest to bardzo proste, wystarczy użyć
dir(
obiektu)
Zwróci listę wszystkich dostępnych funkcji i atrybutów obiektu.
źródło
Inna możliwa opcja, ale zależy to od tego, co masz na myśli wcześniej :
wynik:
Pozwala to nawet sprawdzić atrybuty Bez wartości.
Ale! Uważaj, aby przypadkowo nie utworzyć instancji i nie porównać
undefined
wielu miejsc, ponieważis
w takim przypadku nigdy nie zadziała.Aktualizacja:
z powodu tego, o czym ostrzegałem w powyższym akapicie, mając wiele niezdefiniowanych, które nigdy nie pasują, ostatnio nieznacznie zmodyfikowałem ten wzorzec:
undefined = NotImplemented
NotImplemented
, nie należy mylićNotImplementedError
, jest wbudowany: jest częściowo zgodny z intencją JSundefined
i możesz ponownie użyć jego definicji wszędzie i zawsze będzie pasować. Wadą jest to, że jest „prawdziwa” w logach i może wyglądać dziwnie w logach i śladach na stosie (ale szybko się z tego obchodzisz, gdy wiesz, że pojawia się tylko w tym kontekście).źródło
hasattr()
to właściwa odpowiedź. Chcę dodać, żehasattr()
można go również dobrze używać w połączeniu z aser (aby uniknąć niepotrzebnychif
instrukcji i uczynić kod bardziej czytelnym):Jak stwierdzono w innej odpowiedzi dotyczącej SO : Asertów należy używać do testowania warunków, które nigdy nie powinny się zdarzyć. Celem jest wczesne zawieszenie się w przypadku uszkodzonego stanu programu.
źródło
hasattr
nie otaczającego kodu.