Berücksichtigung von Python-Dekoratoren des Typs, der Variablen übergibt

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)

Referenzmaterial

Über Python Closure: Denken Sie an den Funktionsumfang und die Tatsache, dass die Funktion ein erstklassiges Objekt ist

Recommended Posts

Berücksichtigung von Python-Dekoratoren des Typs, der Variablen übergibt
[Python] Überprüfen Sie den Speicherverbrauch von Variablen
Die Geschichte der Manipulation globaler Python-Variablen
[Python] [Meta] Ist der Python-Typ ein Typ?
Pandas des Anfängers, vom Anfänger, für den Anfänger [Python]
Die Geschichte, dass die Lernkosten von Python niedrig sind
Bildverarbeitung? Die Geschichte, Python für zu starten
Code zum Überprüfen des Betriebs von Python Matplot lib
[Python] Bestimmen Sie den Typ der Iris mit SVM
So ermitteln Sie den Koeffizienten der ungefähren Kurve, die in Python durch die Scheitelpunkte verläuft
der Zen von Python
[Python] Ein Programm, das die Anzahl der Täler zählt
Python-Programm, das nach demselben Dateinamen sucht
Die Einstellung, die Programmierer haben sollten (The Zen of Python)
[Python] Ein Programm, das die Positionen von Kängurus vergleicht.
Ein Python-Skript, das die Anzahl der Jobs für eine bestimmte Bedingung von Indeed.com abruft
Auf dem Weg zum Ruhestand von Python2
Überprüfen Sie die Funktionsweise von Python für .NET in jeder Umgebung
Python --Überprüfen Sie den Wertetyp
Anders als der Importtyp von Python. Bedeutung von aus A Import B.
Verschiedene Hinweise zur Verwendung von Python für Projekte
[Python] Die größten Schwächen und Nachteile von Google Colaboratory [Für Anfänger]
Über die Funktionen von Python
Google sucht mit Python nach der Zeichenfolge in der letzten Zeile der Datei
Python-Skript, das den Inhalt zweier Verzeichnisse vergleicht
Die Kraft der Pandas: Python
Memorandum des Python-Paketverwaltungstools ez_setup
Die Geschichte, dass die Version von Python 3.7.7 nicht an Heroku angepasst wurde
So ändern Sie die Protokollstufe von Azure SDK für Python
Wrap (Teil der) AtCoder Library in Cython zur Verwendung in Python
[Python] Organisieren Sie die Grundstruktur der Flask-App (Ziel des Entkopierens)
Die Geschichte, einen Standardtreiber für db mit Python zu erstellen.
Eine Funktion, die die Verarbeitungszeit einer Methode in Python misst
Überprüfung der Theorie, dass "Python und Swift ziemlich ähnlich sind"
Python Hinweis: Map - Machen Sie dasselbe für jedes Element der Liste
[Python] Ein Hinweis, dass ich das Verhalten von matplotlib.pyplot zu verstehen begann
Die Geschichte, ein Modul zu erstellen, das E-Mails mit Python überspringt
[Python] Ein Programm, das den Inhalt der Liste nach links dreht
Initialisierung globaler Variablen mit Python-Dekoratoren
Die Geschichte von Python und die Geschichte von NaN
Eine gute Beschreibung der Python-Dekorateure
Erster Python 3 ~ Der Beginn der Wiederholung ~
Python für Super-Anfänger Super-Anfänger Python # Wörterbuch Typ 1
Existenz aus Sicht von Python
pyenv-change die Python-Version von virtualenv
Über den Grundtyp von Go
Dies und das von Python-Eigenschaften
[Python] Die potenzielle Feldplanung von Python Robotics verstehen
Überprüfung der Grundlagen von Python (FizzBuzz)
Siehe Python zum ersten Mal
Wofür ist der Python-Unterstrich (_)?
Beherrsche den Typ mit Python [Python 3.9 kompatibel]
Erste Schritte mit Python3