Niedawno przeczytałem o tej getattr()
funkcji . Problem polega na tym, że wciąż nie mogę pojąć jego użycia. Jedyne, co rozumiem, getattr()
to getattr(li, "pop")
to, że dzwonię li.pop
.
Nie rozumiałem, kiedy książka wspomniała, jak go używać, aby uzyskać odniesienie do funkcji, nie znając jej nazwy do czasu wykonania. Może w ogóle to jestem noob w programowaniu. Czy ktoś mógłby rzucić nieco światła na ten temat? Kiedy i jak dokładnie tego używać?
Odpowiedzi:
getattr(object, 'x')
jest całkowicie równoważne zobject.x
.Są tylko dwa przypadki, w których
getattr
może być przydatne.object.x
, ponieważ nie wiesz z góry, który atrybut chcesz (pochodzi z ciągu). Bardzo przydatne do metaprogramowania.object.y
podniesie iAttributeError
jeśli nie may
. Alegetattr(object, 'y', 5)
wróci5
.źródło
Obiekty w Pythonie mogą mieć atrybuty - atrybuty danych i funkcje do pracy z tymi (metodami). Właściwie każdy obiekt ma wbudowane atrybuty.
Na przykład masz obiekt
person
, który ma kilka atrybutów:name
,gender
, itd.Dostęp do tych atrybutów (może to być metody lub obiektów danych) zwykle pisząc:
person.name
,person.gender
,person.the_method()
, itd.Ale co, jeśli nie znasz nazwy atrybutu w momencie pisania programu? Na przykład masz nazwę atrybutu zapisaną w zmiennej o nazwie
attr_name
.gdyby
to zamiast pisać
Możesz pisać
Niektóre praktyki:
getattr
podniesie się,AttributeError
jeśli atrybut o podanej nazwie nie istnieje w obiekcie:Ale możesz przekazać wartość domyślną jako trzeci argument, który zostanie zwrócony, jeśli taki atrybut nie istnieje:
Możesz użyć
getattr
wraz z,dir
aby iterować wszystkie nazwy atrybutów i uzyskać ich wartości:Praktycznym zastosowaniem tego byłoby znalezienie wszystkich metod, których nazwy rozpoczynają się od
test
i wywoływania ich .Podobnie jak
getattr
tam,setattr
który pozwala ustawić atrybut obiektu o nazwie:źródło
getattr(..)
należy tego użyć w 2 scenariuszach: 1. kiedy nazwa atrybutu jest wartością wewnątrz zmiennej (np.getattr(person, some_attr)
) I 2. kiedy musimy użyć trzeciego argumentu pozycyjnego dla wartości domyślnej (npgetattr(person, 'age', 24)
.). Jeśli widzę taki scenariuszgetattr(person, 'age')
, wydaje mi się, że jest identyczny,person.age
co prowadzi mnie do myślenia, żeperson.age
jest bardziej pythoniczny. Czy to jest poprawne?Dla mnie,
getattr
najłatwiej to wytłumaczyć w ten sposób:Pozwala na wywoływanie metod na podstawie zawartości ciągu zamiast wpisywania nazwy metody.
Na przykład nie możesz tego zrobić:
ponieważ x nie jest tego typu
builtin
, alestr
. Możesz jednak to zrobić:Pozwala dynamicznie łączyć się z obiektami na podstawie wprowadzonych danych. Uznałem, że jest to przydatne w przypadku niestandardowych obiektów i modułów.
źródło
Dość powszechny przypadek użycia dla
getattr
jest mapowanie danych do funkcji.Na przykład w frameworku internetowym, takim jak Django lub Pylons,
getattr
ułatwia mapowanie adresu URL żądania internetowego na funkcję, która będzie go obsługiwać. Jeśli na przykład spojrzysz pod maską routingu Pylons, zobaczysz, że (przynajmniej domyślnie) tnie adres URL żądania, na przykład:na „klientów” i „listę”. Następnie szuka klasy kontrolera o nazwie
CustomerController
. Zakładając, że znajdzie klasę, tworzy instancję klasy, a następnie używagetattr
jej do uzyskanialist
metody. Następnie wywołuje tę metodę, przekazując jej żądanie jako argument.Po zrozumieniu tego pomysłu bardzo łatwo jest rozszerzyć funkcjonalność aplikacji internetowej: po prostu dodaj nowe metody do klas kontrolerów, a następnie utwórz linki na swoich stronach, które używają odpowiednich adresów URL dla tych metod. Wszystko to jest możliwe dzięki
getattr
.źródło
Oto szybki i nieprzyzwoity przykład tego, w jaki sposób klasa może uruchamiać różne wersje metody składowania w zależności od używanego systemu operacyjnego
getattr()
.Teraz użyjmy tej klasy w przykładzie:
źródło
Oprócz wszystkich niesamowitych odpowiedzi tutaj jest sposób na użycie
getattr
na zapisanie dużej liczby wierszy kodu i utrzymanie go w dobrym stanie. Ta myśl pojawiła się w następstwie okropnego przedstawienia kodu, co czasami może być koniecznością.Scenariusz
Załóżmy, że twoja struktura katalogów jest następująca:
I masz funkcje do uzyskiwania informacji na temat
Thor
,Iron Man
,Doctor Strange
wsuperheroes.py
. Bardzo mądrze zapisujesz właściwości wszystkich z nichproperties.py
w formie kompaktowej,dict
a następnie uzyskujesz do nich dostęp.properties.py
Powiedzmy, że chcesz zwrócić możliwości każdego z nich na żądanie
superheroes.py
. Istnieją więc funkcje takie jak... i więcej funkcji zwracających różne wartości na podstawie klawiszy i superbohatera.
Z pomocą
getattr
możesz zrobić coś takiego:Znacząco zmniejszyłeś liczbę wierszy kodu, funkcji i powtórzeń!
No i oczywiście, jeśli masz złe nazwy, takie jak
properties_of_thor
zmienne, można je utworzyć i uzyskać do nich dostęp po prostu przez zrobienieUWAGA: W przypadku tego konkretnego problemu mogą istnieć mądrzejsze sposoby radzenia sobie z sytuacją, ale chodzi o to, aby dać wgląd
getattr
w korzystanie z odpowiednich miejsc do pisania czystszego kodu.źródło
źródło
Czasami
getattr(..)
leniwie inicjuję atrybuty o drugorzędnym znaczeniu tuż przed ich użyciem w kodzie.Porównaj następujące:
Do tego:
Zaletą drugiego sposobu jest to, że
n_calls_to_plot
pojawia się tylko wokół miejsca w kodzie, w którym jest używany. Jest to dobre z punktu widzenia czytelności, ponieważ (1) możesz od razu zobaczyć, od jakiej wartości zaczyna się czytając, w jaki sposób jest on używany, (2) nie wprowadza rozproszenia w__init__(..)
metodzie, co idealnie powinno dotyczyć stanu koncepcyjnego klasy , zamiast jakiegoś licznika narzędzi, który jest używany tylko przez jedną z metod funkcji z przyczyn technicznych, takich jak optymalizacja, i nie ma nic wspólnego ze znaczeniem obiektu.źródło
Dość często, gdy tworzę plik XML z danych przechowywanych w klasie, często otrzymuję błędy, jeśli atrybut nie istnieje lub jest typu
None
. W tym przypadku mój problem nie polegał na nieznajomości nazwy atrybutu, jak podano w pytaniu, ale raczej na danych przechowywanych w tym atrybucie.Gdybym
hasattr
to robił, zwróciłobyTrue
to wartość, nawet jeśli wartość atrybutu była typu,None
a to spowodowałoby niepowodzenie mojejset
komendy ElementTree .Jeśli wartość atrybutu byłaby typu
None
,getattr
zwróciłaby ją również, co spowodowałoby niepowodzenie mojejset
komendy ElementTree .Korzystam z następującej metody, aby zająć się teraz tymi sprawami:
To jest kiedy i jak używam
getattr
.źródło
Kolejne zastosowanie getattr () w implementacji instrukcji switch w Pythonie. Używa obu odbić, aby uzyskać typ sprawy.
źródło
setattr ()
Używamy setattr, aby dodać atrybut do naszej instancji klasy. Przekazujemy instancję klasy, nazwę atrybutu i wartość.
getattr ()
W getattr odzyskujemy te wartości
Na przykład
źródło
Myślę, że ten przykład jest oczywisty. Działa metoda pierwszego parametru, którego nazwa jest podana w drugim parametrze.
źródło
Wyjaśnia to również https://www.programiz.com/python-programming/methods/built-in/getattr
Wiek to: 23 lata
Wiek to: 23 lata
Płeć to: mężczyzna
AttributeError: Obiekt „Osoba” nie ma atrybutu „seks”
źródło
Próbowałem w Python2.7.17
Niektórzy inni już odpowiedzieli. Jednak próbowałem wywołać getattr (obj, 'set_value') i to nie wykonało metody set_value, więc zmieniłem na getattr (obj, 'set_value') () -> To pomaga wywołać to samo.
Przykładowy kod:
Przykład 1:
źródło