Chociaż lubię myśleć o sobie jako o dość kompetentnym kodzie Pythona, jednym z aspektów języka, którego nigdy nie byłem w stanie zrozumieć, są dekoratorzy.
Wiem, czym one są (powierzchownie), przeczytałem samouczki, przykłady, pytania na temat przepełnienia stosu i rozumiem składnię, mogę pisać własne, czasami używam @classmethod i @staticmethod, ale nigdy nie przychodzi mi do głowy, aby użyć dekorator, aby rozwiązać problem we własnym kodzie Python. Nigdy nie spotykam problemu, w którym myślę: „Hmm… to wygląda jak praca dla dekoratora!”
Zastanawiam się, czy moglibyście podać przykłady zastosowania dekoratorów we własnych programach i mam nadzieję, że będę miał „A-ha!” chwila i zdobądź je.
functools.lru_cache
który robi dokładnie to, co powiedział Peter, od Python 3.2, wydany w lutym 2011 roku.Odpowiedzi:
Używam dekoratorów głównie do pomiaru czasu
źródło
time.clock()
mierzy czas procesora. Możesztime.time()
zamiast tego użyć, jeśli chcesz zmierzyć czas naścienny.myFunction
do uruchomienia ...Użyłem ich do synchronizacji.
Jak wskazano w komentarzach, od Python 2.5 można używać
with
instrukcji w połączeniu zthreading.Lock
(lubmultiprocessing.Lock
od wersji 2.6), aby uprościć implementację dekoratora do:Niezależnie od tego używasz go w następujący sposób:
Zasadniczo po prostu umieszcza
lock.acquire()
/lock.release()
po obu stronach wywołania funkcji.źródło
Korzystam z dekoratorów do sprawdzania parametrów, które są przekazywane do moich metod Python za pośrednictwem niektórych RMI. Zamiast więc powtarzać liczenie tego samego parametru, mumbo-jumbo podnoszące wyjątki raz po raz.
Na przykład zamiast:
Po prostu deklaruję:
i
accepts()
wykonuje całą pracę dla mnie.źródło
@accepts
w PEP 318.isinstance()
funkcja, tak jak ma to miejsce w implementacji dekoratora przez PEP 318 . Ponieważ jegoclassinfo
argumentem może być jeden lub więcej typów, użycie go złagodziłoby również (prawidłowe) zastrzeżenia @ Gustavo6046. Python ma równieżNumber
abstrakcyjną klasę podstawową, więcisinstance(42, numbers.Number)
możliwe są bardzo ogólne testy .Dekoratory służą do wszystkiego, co chcesz transparentnie „zawinąć” z dodatkową funkcjonalnością.
Django używa ich do pakowania funkcji „wymagane logowanie” do funkcji przeglądania , a także do rejestrowania funkcji filtrów .
Do dodawania nazwanych dzienników do klas można użyć dekoratorów klas .
Każda wystarczająco ogólna funkcjonalność, którą można „przyczepić” do istniejącego zachowania klasy lub funkcji, jest uczciwą grą dla dekoracji.
W grupie dyskusyjnej Python-Dev omawia się także przypadki użycia, na które wskazuje PEP 318 - Dekoratorzy funkcji i metod .
źródło
W przypadku testów nosa możesz napisać dekorator, który udostępnia funkcję lub metodę testu jednostkowego z kilkoma zestawami parametrów:
źródło
Biblioteka Twisted używa dekoratorów w połączeniu z generatorami, aby dać złudzenie, że funkcja asynchroniczna jest synchroniczna. Na przykład:
Korzystając z tego, kod, który zostałby rozbity na mnóstwo małych funkcji zwrotnych, można napisać całkiem naturalnie jako pojedynczy blok, co znacznie ułatwia jego zrozumienie i utrzymanie.
źródło
Jednym z oczywistych zastosowań jest oczywiście logowanie:
źródło
Używam ich głównie do debugowania (owijania wokół funkcji, która wypisuje jej argumenty i wyniki) i weryfikacji (np. Do sprawdzania, czy argument jest poprawnego typu lub, w przypadku aplikacji internetowej, czy użytkownik ma wystarczające uprawnienia do wywołania określonego metoda).
źródło
Korzystam z następującego dekoratora do tworzenia funkcji wątkowo bezpiecznej. Dzięki temu kod jest bardziej czytelny. Jest prawie podobny do zaproponowanego przez Johna Fouhy, ale różnica polega na tym, że działa się na jednej funkcji i nie ma potrzeby jawnego tworzenia obiektu blokady.
źródło
Dekoratory są używane albo do zdefiniowania właściwości funkcji, albo jako płyta zmieniająca ją; jest możliwe, ale sprzeczne z intuicją, aby zwracały zupełnie inne funkcje. Patrząc na inne odpowiedzi tutaj, wydaje się, że jednym z najczęstszych zastosowań jest ograniczenie zakresu innego procesu - rejestrowania, profilowania, kontroli bezpieczeństwa itp.
CherryPy używa wysyłania obiektów, aby dopasować adresy URL do obiektów i, ostatecznie, metod. Dekoratorzy na tych metod sygnalizować czy CherryPy jest nawet dopuszczone do stosowania tych metod. Na przykład adaptacja z samouczka :
źródło
Ostatnio ich używałem, pracując nad aplikacją sieci społecznościowych. W przypadku społeczności / grup miałem upoważnić członka do utworzenia nowej dyskusji i odpowiedzi na wiadomość, że musisz być członkiem tej konkretnej grupy. Napisałem dekoratora
@membership_required
i umieściłem go tam, gdzie tego wymagałem.źródło
Używam tego dekoratora do naprawy parametru
to napisane, gdy refaktoryzuję, niektóre funkcje muszą przekazać argument „wanN”, ale w moich starych kodach przekazałem tylko N lub „N”
źródło
Dekorator może być używany do łatwego tworzenia zmiennych metod funkcji.
źródło