Bei der Entwicklung mit Python gibt es meiner Meinung nach viele Fälle, in denen Sie eine gemeinsame Verarbeitung vor und nach einer Funktion durchführen möchten. In diesem Fall wird häufig der Dekorator verwendet (der die Zeile über der Funktion mit Anmerkungen versehen). In diesem Artikel möchte ich die grundlegende Verwendung von Dekoratoren und die Arten von Dekoratoren betrachten, die in der zweiten Hälfte Variablen übergeben können.
Der einfachste Dekorateur ist die folgende Implementierung.
def decorator(func):
def decorated(*args, **kwargs):
print('Dekorierter Start')
func(*args, **kwargs)
print('Dekoriertes Ende')
return decorated
Gehen Sie wie folgt vor, um diesen Dekorator tatsächlich zu verwenden.
@decorator
def sample(name):
print('{}Hat funktioniert.'.format(name))
Wenn diese dekorierte Beispielfunktion ausgeführt wird, wird sie wie folgt gedruckt. Sie können sehen, dass die Verarbeitung erwartungsgemäß vor und nach der Beispielfunktion eingefügt wird.
Dekorierter Start
Probe gearbeitet.
Dekoriertes Ende
Der Grund, warum es so funktioniert, ist, dass @ Syntaxzucker ist Dies liegt daran, dass es tatsächlich dem folgenden Code entspricht.
def sample(name):
print('{}Hat funktioniert.'.format(name))
# @Entspricht dem Dekorateur
sample = decorator(sample)
Bisher ist es relativ einfach zu verstehen, aber ich denke, dass es viele Fälle gibt, in denen Sie stecken bleiben, wenn Sie versuchen, den Typ des Dekorateurs zu verstehen, der Variablen übergeben kann.
def annotation(param):
print('Anmerkungsstart')
def decorator(func):
print('Starten Sie den Dekorateur')
print('param:{}'.format(param))
def decorated(*args, **kwargs):
print('Dekorierter Start')
print('param:{}'.format(param))
func(*args, **kwargs)
print('Dekoriertes Ende')
print('Dekorateur fertig')
return decorated
print('Anmerkungsende')
return decorator
Sollte das Argument der Funktion der obersten Ebene (Annotation) angesichts der zuvor erwähnten Bewegung der Syntax Zucker (@) nicht eine Funktion sein müssen? Es ist leicht zu denken, aber der folgende Code funktioniert tatsächlich gut.
print('Definieren Sie eine mit Anmerkungen versehene Funktion')
@annotation(param=999)
def sample(name):
print('{}Hat funktioniert.'.format(name))
print('Führen Sie eine kommentierte Funktion aus')
sample('sample')
Die Druckausgabe wird unten angezeigt
Definieren Sie eine mit Anmerkungen versehene Funktion
Anmerkungsstart
Anmerkungsende
Starten Sie den Dekorateur
param:999
Dekorateur fertig
Führen Sie eine kommentierte Funktion aus
Dekorierter Start
param:999
Probe gearbeitet.
Dekoriertes Ende
Betrachten Sie die Druckausgabe oben unter den Dekorationsfunktionen, die nach dem Ende der Anmerkungsfunktion aufgerufen werden Sie können auf param verweisen, das das Argument der Anmerkungsfunktion ist. Der Grund für dieses Verhalten ist, dass die Variablen, auf die sich die Funktion beziehen kann, bestimmt werden, wenn die Funktion definiert wird, sodass die in der Anmerkungsfunktion definierte Dekorationsfunktion auf den Parameter verweisen kann, der das Argument der Anmerkungsfunktion ist. Weil.
In Anbetracht des Inhalts der Druckausgabe wird der Syntaxzucker (@) des Dekoratortyps, der Variablen übergeben kann, als dem folgenden äquivalent angesehen.
def sample(name):
print('{}Hat funktioniert.'.format(name))
# @annotation(param=999)Gleichwertig
sample = annotation(param=999)(sample)
Recommended Posts