jesteś tutaj
397
Dekoratory funkcji
Tworzenie dekoratora funkcji
Aby spełnić wymóg stawiany przez 1. punkt naszej listy, musisz utworzyć nową funkcję. Pamiętaj, że:
Dekorator jest funkcją.
W rzeczywistości z punktu widzenia interpretera dekorator jest po prostu kolejną
funkcją, aczkolwiek taką, która manipuluje inną, istniejącą już funkcją. ostatnią
będziemy od tej pory określać mianem
funkcji dekorowanej. Dzięki lekturze
wcześniejszej części tej książki wiesz już, że tworzenie funkcji to nic trudnego;
wystarczy tu skorzystać ze słowa kluczowego
def
języka Python.
Spełnienie wymogu określonego w punkcie 2. polega na sprawieniu, aby dekorator przyjmował
obiekt funkcji jako swój argument. Ponownie, pamiętaj, że:
Dekorator przyjmuje dekorowaną funkcję jako argument.
Dekorator musi przyjmować dekorowaną funkcję jako swój argument. Aby do
niego przesłać, powinieneś po prostu przekazać do dekoratora funkcję dekorowaną
jako
obiekt funkcji. Po lekturze ostatnich 10 stron tej książki wiesz już, że to też
jest proste; do obiektu funkcji można się odwołać, używając samej jej nazwy
bez
nawiasów (ponieważ nawiasy informują interpreter, że funkcja ma być wywołana).
Umieśćmy nasz dekorator w osobnym, jego własnym module (aby dało się go łatwiej
ponownie wykorzystywać). Zacznij od utworzenia nowego pliku o nazwie
checker.py
za pomocą swojego edytora kodu.
W pliku tym powinieneś opracowdekorator o nazwie check_logged_in. W miejscu
zapewnionym poniżej wprowadź kod stanowiący wiersz def tego dekoratora. Wskazówka:
jako nazwy swojego argumentu odpowiedzialnego za przekazanie obiektu funkcji użyj
ciągu func.
Umieść wiersz def
dekoratora w tym miejscu.
P
: Czy to, gdzie w moim systemie utworzę plik checker.py, ma jakieś znaczenie?
O
:
Tak. Planujemy importować plik checker.py w kodzie aplikacji WWW, która będzie go potrzebować, dlatego
powinieneś zapewnić, żeby interpreter był w stanie odszukać ten plik, gdy w Twoim kodzie pojawi się instrukcja
import
checker
. Na razie umieść plik checker.py w tym samym folderze, w którym znajduje się plik simple_webapp.py.
1
2
Zaostrz ołówek
głupie pytania
Nie istnieją
398
Rozdział 10.
Dekorator nabiera kształtu
Zaostrz ołówek
Rozwiązanie
def check_logged_in(func):
Dekorator check_logged_in przyjmuje
pojedynczy argument, którym jest obiekt
dekorowanej funkcji.
def outer():
def inner():
print(‘To jest funkcja inner.’)
print(‘To jest funkcja outer, wywołująca funkcję inner.’)
return inner
Funkcja inner jest
zagnieżdżona wewnątrz
funkcji outer.
Cały ten kod
znajduje się
wewnątrz
zestawu funkcji
outer.
Obiekt funkcji inner jest zwracany jako wynik
wywołania funkcji outer. Zauważ brak nawiasów po
słowie inner wynikający z tego, że jest tu zwracany
obiekt funkcji, a NIE wywoływana funkcja inner.
Postanowiliśmy umieścić nasz dekorator w osobnym module (aby dało się go łatwiej ponownie
wykorzystywać).
Zacząłeś od utworzenia nowego pliku o nazwie
checker.py
za pomocą swojego edytora kodu.
Twój nowy dekorator (znajdujący się w pliku
checker.py
) nosi nazwę check_logged_in. W miejscu
zapewnionym poniżej miałeś wprowadzić kod stanowiący wiersz def tego dekoratora.
To niemal zbyt proste, czyż nie?
Pamiętaj, że dekorator to po prostu kolejna funkcja, która przyjmuje obiekt funkcji jako swój argument
(noszący w przypadku przedstawionego powyżej wiersza
def
nazwę
func
).
Przejdźmy do następnego punktu naszego „przepisu tworzenia dekoratora”, który jest nieco bardziej
skomplikowany (ale tylko nieco). Przypomnij sobie, co powinien robić Twój dekorator:
Dekorator zwraca nową funkcję.
Dekorator zwraca nową funkcję jako swoją wartość zwracaną. Odbywa się to
podobnie, jak było w przypadku funkcji
outer
, która zwracała funkcję
inner
(kilka stron wcześniej). Dekorator działa bardzo podobnie, z różnicą, że
zwracana funkcja
musi wywoływać funkcję dekorowaną.
3
We wcześniejszej części tego rozdziału miałeś do czynienia z funkcją
outer
, której wywołanie
powodowało zwrócenie funkcji
inner
. Poniżej jeszcze raz zaprezentowaliśmy kod tej funkcji.
jesteś tutaj
399
Dekoratory funkcji
Gdy napisałeś już wiersz def swojego dekoratora, dodaj do jego zestawu trochę kodu. Powinieneś
zrobić tu cztery rzeczy.
1. Zdefiniuj zagnieżdżoną funkcję o nazwie wrapper, która jest zwracana przez funkcję
check_logged_in. (Mógłbyś tu użyć dowolnej nazwy, ale — jak przekonasz się już wkrótce
— nazwa wrapper jest całkiem dobrym wyborem).
2. Do funkcji wrapper dodaj trochę kodu pochodzącego z Twojej istniejącej funkcji check_status.
Chodzi tu o kod implementujący jedno z dwóch działań uzależnionych od tego, czy użytkownik
przeglądarki jest zalogowany, czy też nie. Aby zaoszczędzić Ci przerzucania kartek, poniżej raz
jeszcze zamieściliśmy kod funkcji check_status (istotne części tego kodu zostały wyróżnione).
@app.route(‘/status’)
def check_status() -> str:
if ‘logged_in’ in session:
return ‘W tej chwili jesteś zalogowany.’
return ‘NIE jesteś zalogowany.’
3. Zgodnie z 3. punktem naszego przepisu tworzenia dekoratora powinieneś sprawić, aby zagnieżdżona
funkcja wywoływała funkcję dekorowaną (zamiast zwracać komunikat o treści „W tej chwili jest
zalogowany”, jak ma to miejsce powyżej).
4. Gdy zagnieżdżona funkcja będzie już gotowa, powinieneś zapewnić, aby jej obiekt był zwracany
przez funkcję check_logged_in.
Dodaj niezbędny kod do zestawu funkcji check_logged_in we wskazanych poniżej miejscach.
def check_logged_in(func):
1. Zdefiniuj
zagnieżdżoną
funkcję.
4. Nie zapomnij
o zwróceniu
zagnieżdżonej funkcji.
2. i 3. Dodaj
kod, który
ma być
wykonywany
przez
zagnieżdżoną
funkcję.
Zaostrz ołówek

Get Python Rusz głową! Wydanie II now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.