Zlecenie wykonania dekoratora
def make_bold(fn):
return lambda : "<b>" + fn() + "</b>"
def make_italic(fn):
return lambda : "<i>" + fn() + "</i>"
@make_bold
@make_italic
def hello():
return "hello world"
helloHTML = hello()
Wyjście: "<b><i>hello world</i></b>"
Z grubsza Rozumiem o dekoratorach i jak to działa z jednym z nich w większości przykładów.
W tym przykładzie jest ich 2. Z wyjścia wynika, że @make_italic
uruchamia się najpierw, a następnie @make_bold
.
Czy to oznacza, że dla dekorowanych funkcji, najpierw uruchomi funkcję, a następnie przesunie się do góry dla innych dekoratorów? Jak @make_italic
Najpierw @make_bold
, a nie odwrotnie.
Więc oznacza to, że jest różni się od normy podejścia odgórnego w większości języków programowania? Tylko dla tego dekoratora? A może się mylę?
1 answers
Dekoratorzy owijają funkcję, którą dekorują. Więc make_bold
dekoruje wynik make_italic
dekoratora, który dekoruje hello
funkcję.
Składnia @decorator
jest tak naprawdę tylko cukrem składniowym; następujące:
@decorator
def decorated_function():
# ...
Jest tak naprawdę wykonywany jako:
def decorated_function():
# ...
decorated_function = decorator(decorated_function)
Zastąpienie oryginalnego obiektu decorated_function
zwracanym obiektem decorator()
.
Układanie dekoratorów powtarza ten proces Na Zewnątrz .
Więc twoja próbka:
@make_bold
@make_italic
def hello():
return "hello world"
Może być rozszerzono do:
def hello():
return "hello world"
hello = make_bold(make_italic(hello))
Kiedy wywołujesz hello()
teraz, wywołujesz obiekt zwrócony przez make_bold()
, naprawdę. make_bold()
zwrócił lambda
, który wywołuje funkcję make_bold
owiniętą, która jest wartością zwracaną make_italic()
, która jest również lambda, która wywołuje Oryginalny hello()
. Rozszerzenie wszystkich tych połączeń, które otrzymujesz:
hello() = lambda : "<b>" + fn() + "</b>" # where fn() ->
lambda : "<i>" + fn() + "</i>" # where fn() ->
return "hello world"
Więc wyjście staje się:
"<b>" + ("<i>" + ("hello world") + "</i>") + "</b>"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-07 11:45:42