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()
Ausgabe: "<b><i>hello world</i></b>"
Ich verstehe grob über Dekorateure und wie es mit einem davon in den meisten Beispielen funktioniert.
In diesem Beispiel gibt es zwei davon. Aus der Ausgabe geht hervor, dass diese @make_italic
zuerst ausgeführt wird @make_bold
.
Bedeutet dies, dass bei dekorierten Funktionen zuerst die Funktion ausgeführt wird und dann bei anderen Dekorateuren nach oben verschoben wird? Wie @make_italic
zuerst dann @make_bold
, anstatt das Gegenteil.
Das bedeutet also, dass es sich in den meisten Programmiersprachen von der Norm des Top-Down-Ansatzes unterscheidet? Nur für diesen Fall von Dekorateur? Oder liege ich falsch?
python
decorator
python-decorators
Neuling
quelle
quelle
a(b(x))
es von oben nach unten ist (wenn Sie sich vorstellen, dass es sich um 3 Zeilen handelt)Antworten:
Dekorateure verpacken die Funktion, die sie dekorieren. So
make_bold
dekorierte das Ergebnis desmake_italic
Dekorateurs, der diehello
Funktion dekorierte .Die
@decorator
Syntax ist wirklich nur syntaktischer Zucker; folgende:wird wirklich ausgeführt als:
Ersetzen des ursprünglichen
decorated_function
Objekts durch dasdecorator()
zurückgegebene Objekt .Das Stapeln von Dekorateuren wiederholt diesen Vorgang nach außen .
Also deine Probe:
kann erweitert werden auf:
Wenn Sie
hello()
jetzt aufrufen , rufen Sie das vonmake_bold()
wirklich zurückgegebene Objekt auf .make_bold()
hat a zurückgegebenlambda
, das diemake_bold
umschlossene Funktion aufruft. Dies ist der Rückgabewert vonmake_italic()
. Dies ist auch ein Lambda, das das Original aufrufthello()
. Wenn Sie all diese Anrufe erweitern, erhalten Sie:so wird die Ausgabe:
quelle
@make_bold #make_bold = make_bold(hello)
@make_italic #make_italic = make_italic (hello)
? Ich bin mir nicht sicher, ob das erste Ergebnis darauf basiert. Oder wird für diesen Fall von 2 Wrappern die IDEmake_bold(make_italic(hello))
wie von Ihnen erwähnt anstelle der von mir freigegebenen verwendet?make_bold()
die Ausgabe vonmake_italic()
, die zum Umschließen verwendet wurdehello
, das Äquivalent von umschließtmake_bold(make_italic(hello))
.def inner: return "<b>" + fn() + "</b>"
, Dannreturn inner
wäre die ‚normale‘ Funktion Version; kein so großer Unterschied.make_italic
Dekorator vor demmake_bold
Dekorator ausgeführt wird , da er demmake_italic
am nächsten liegtdef
. Ich vergesse jedoch die Reihenfolge der Ausführung des dekorierten Codes: Dasmake_bold
dekorierte (dh fette Lambda) wird zuerst ausgeführt, gefolgt vommake_italic
dekorierten Lambda (dh dem kursiven Lambda).