Zunächst weiß ich, was ein Dekorateur ist. Ich würde gerne einige kleine Aspekte verstehen.Wie ist ein Python-Dekorator tatsächlich definiert?
TL; DR
is decorator func1 = func2(func1) # True
is decorator func3 = func2(func1) # ???
die bei Wiki Schauen wir uns die zwei gleichwertige Wege beschreibt, eine Funktion dekorieren:
@viking_chorus
def menu_item():
print("spam")
def menu_item():
print("spam")
menu_item = viking_chorus(menu_item)
Jetzt wollen wir die Beschreibung zu diesem website sehen, besonders im Abschnitt Zurück zu Dekoratoren. Es gibt zwei Funktionen definiert:
def make_pretty(func):
def inner():
print("I got decorated")
func()
return inner
def ordinary():
print("I am ordinary")
Und dann schmückt ein Autor die Funktion und nennt es:
>>> pretty = make_pretty(ordinary)
>>> pretty()
I got decorated
I am ordinary
Wir bemerken, dass der Autor nicht nicht verwendet:
>>> ordinary = make_pretty(ordinary)
die ist ein empfohlener Weg durch Wiki (Ich weiß, dass Wiki manchmal falsch sein kann). Also beschloss ich, die letzte Art und Weise zu verwenden, um die Fibonacci-Zahlen-Funktion von diesen tutorial genommen zu dekorieren:
def memoize(f):
memo = {}
def helper(x):
if x not in memo:
memo[x] = f(x)
return memo[x]
return helper
def fib(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fib(n-1) + fib(n-2)
Dieser Aufruf:
>>> fib_element = memoize(fib)
>>> fib_element(40)
dauert eine lange Zeit auf meiner Maschine, was bedeutet, dass die fib()
gewesen nicht richtig dekoriert. Die Ausführungszeit ist vergleichbar mit fib(40)
. Diese Anrufe:
>>> fib = memoize(fib)
>>> fib_element = fib # assigned after decoration
>>> fib(40)
>>> fib_element(40)
schnell ausgeführt werden. Die Frage ist also: Können wir sagen, dass wir die ordinary
Funktion in pretty = make_pretty(ordinary)
Zuweisung schmücken?
Technisch gibt es kein eindeutiges Objekt, das Decorator genannt wird; es ist wirklich nur eine Funktion, die eine Funktion als Argument nimmt und eine andere Funktion zurückgibt (oder voraussichtlich zurückgibt). Was * ist * besonders ist Dekorator * Syntax *, die eine übersichtliche Möglichkeit bietet, die Decorator-Funktion anzuwenden. '@foo def bar(): ...' ist kürzer als 'def bar(): ...; bar = foo (bar) '. – chepner