Einführung
Dieser Abschnitt stellt das Konzept eines Dekorators vor. Dies ist ein fortgeschrittenes Thema, von dem wir nur die Oberfläche streifen.
This tutorial is from open-source community. Access the source code
💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken
Dieser Abschnitt stellt das Konzept eines Dekorators vor. Dies ist ein fortgeschrittenes Thema, von dem wir nur die Oberfläche streifen.
Betrachten Sie eine Funktion.
def add(x, y):
return x + y
Nun betrachten Sie die Funktion mit etwas Logging hinzugefügt.
def add(x, y):
print('Calling add')
return x + y
Nun eine zweite Funktion ebenfalls mit etwas Logging.
def sub(x, y):
print('Calling sub')
return x - y
Beobachtung: Es ist ziemlich repetitiv.
Das Schreiben von Programmen, in denen es eine Menge Codewiederholungen gibt, ist oft wirklich ärgerlich. Sie sind langweilig zu schreiben und schwer zu warten. Vor allem, wenn Sie sich entscheiden, wie es funktioniert zu ändern (z. B. vielleicht eine andere Art von Logging).
Vielleicht können Sie eine Funktion schreiben, die Funktionen mit hinzugefügtem Logging erstellt. Ein Wrapper.
def logged(func):
def wrapper(*args, **kwargs):
print('Calling', func.__name__)
return func(*args, **kwargs)
return wrapper
Nun verwenden Sie es.
def add(x, y):
return x + y
logged_add = logged(add)
Was passiert, wenn Sie die von logged
zurückgegebene Funktion aufrufen?
logged_add(3, 4) ## Sie sehen die Log-Nachricht erscheinen
Dieses Beispiel veranschaulicht den Prozess des Erstellens einer sogenannten Wrapper-Funktion.
Ein Wrapper ist eine Funktion, die um eine andere Funktion herumgeht und einige zusätzliche Verarbeitungsbits hat, aber sonst genauso funktioniert wie die ursprüngliche Funktion.
>>> logged_add(3, 4)
Calling add ## Zusätzliche Ausgabe. Hinzugefügt durch den Wrapper
7
>>>
Hinweis: Die logged()
-Funktion erstellt den Wrapper und gibt ihn als Ergebnis zurück.
Das Umhüllen von Funktionen mit Wrappern ist in Python extrem üblich. So üblich, dass es eine spezielle Syntax dafür gibt.
def add(x, y):
return x + y
add = logged(add)
## Spezielle Syntax
@logged
def add(x, y):
return x + y
Die spezielle Syntax führt genau die gleichen Schritte wie oben gezeigt aus. Ein Dekorator ist einfach nur neue Syntax. Man sagt, dass er die Funktion dekoriert.
Es gibt viele subtlere Details zu Dekoratoren, als hier dargestellt wurden. Beispielsweise das Verwenden von Dekoratoren in Klassen. Oder das Verwenden mehrerer Dekoratoren für eine Funktion. Der vorherige Beispiel ist jedoch eine gute Illustration davon, wie ihre Verwendung typischerweise entsteht. Normalerweise tritt dies in der Antwort auf wiederkehrenden Code, der in einer Vielzahl von Funktionsdefinitionen auftritt. Ein Dekorator kann diesen Code in eine zentrale Definition verschieben.
Wenn Sie eine Funktion definieren, werden ihr Name und ihr Modul in den Attributen __name__
und __module__
gespeichert. Beispielsweise:
>>> def add(x,y):
return x+y
>>> add.__name__
'add'
>>> add.__module__
'__main__'
>>>
In einer Datei timethis.py
schreiben Sie einen Dekoratorfunktion timethis(func)
, der eine Funktion mit einer zusätzlichen Logikschicht umschließt, die ausgibt, wie lange es für eine Funktion dauert, bis sie ausgeführt wird. Dazu umschließen Sie die Funktion mit Zeitmessaufrufen wie folgt:
start = time.time()
r = func(*args,**kwargs)
end = time.time()
print('%s.%s: %f' % (func.__module__, func.__name__, end-start))
Hier ist ein Beispiel dafür, wie Ihr Dekorator funktionieren sollte:
>>> from timethis import timethis
>>> @timethis
def countdown(n):
while n > 0:
n -= 1
>>> countdown(10000000)
__main__.countdown : 0.076562
>>>
Diskussion: Dieser @timethis
-Dekorator kann vor jeder Funktionsdefinition platziert werden. Somit können Sie ihn als diagnostisches Tool für die Leistungstuning verwenden.
Herzlichen Glückwunsch! Sie haben das Lab zu Funktionsdekorationen abgeschlossen. Sie können in LabEx weitere Labs absolvieren, um Ihre Fähigkeiten zu verbessern.