Ich kann dich nicht noch einmal fragen (?) Python Knowledge Series -Decorator-

Einführung

Klassen, Methoden, Iteratoren, Konstruktoren ... Bei der Programmierung mit Python (ohne darauf beschränkt zu sein) tauchen viele technische Begriffe und Konzepte auf. Hier erkläre ich die Begriffe und die Verwendung, die ich nicht mehr hören kann, einschließlich der Bedeutung von Flammenlernen.

Der erste ist decorator. (Es ist unentschlossen, ob das zweite Mal gemacht werden soll)

Was ist ein Dekorateur?

Kurz gesagt, es ist __, das der __-Funktion Funktionalität verleiht. Schauen wir uns trotzdem einen Beispielcode an.

print_args_decorator.py


# -*- coding: utf-8 -*-
#Dekorateur zum Anzeigen von Argumenten
def print_args(func):
    def wrapper(*args, **kwargs):
        res = func(*args, **kwargs)
        print('<args is ...>')
        for arg in args:
            print(arg)
        for kwarg in kwargs:
            print('{0}:{1}'.format(kwarg, kwargs[kwarg]))
        return res
    return wrapper

Lassen Sie uns die Funktion mit diesem Dekorator dekorieren. Bereiten Sie die Funktion vor.

seimei.py


# -*- coding: utf-8 -*-
def seimei(LastName, FirstName):
    """Zeigen Sie das Argument als Namen an"""
    print('Vollständiger Name:{0} {1}'.format(FirstName, LastName))

if __name__ == '__main__':
    seimei(LastName='Jackson', FirstName='Michael')
Vollständiger Name:Michael Jackson

Wir erhalten den Vor- und Nachnamen und geben ihn als Namen aus. Was ist, wenn Sie den zuvor erstellten Dekorator hinzufügen?

seimei_deco.py


# -*- coding: utf-8 -*-
from print_args_decorator import print_args

@print_args  #Dekorateur
def seimei(LastName, FirstName):
    """Zeigen Sie das Argument als Namen an"""
    print('Vollständiger Name:{0} {1}'.format(FirstName, LastName))

if __name__ == '__main__':
    seimei(LastName='Jackson', FirstName='Michael')
Vollständiger Name:Michael Jackson
<args is ...>
LastName:Jackson
FirstName:Michael

Der Wert des Arguments wird jetzt zusammen mit der Ausgabe der ursprünglichen Funktion ausgegeben. Dies liegt daran, dass die Funktion, die den Namen zurückgibt, die Funktion erhält, __arguments __ auszugeben. Ich weiß nicht, was es ist, aber es scheint bequem

Wie man einen Dekorateur macht

Was im Inneren des Dekorateurs passiert, wird in den folgenden Artikeln ausführlich erklärt.

Anhand dieses Artikels und des obigen Beispielcodes werde ich die grundlegende Funktionsweise des Dekorateurs erläutern. (Da das oben Gesagte auch den Umfang berührt, der ein wichtiges Konzept bei der Programmierung darstellt, wird Anfängern von Python empfohlen, ihn zu lesen.)

Empfangsfunktion und Rückgabefunktion

Erstellen Sie zunächst ein Teil, das als Dekorateur fungiert. Im Beispielcode ist dies die Hierarchie von `def print_args (func):`. Diese Funktion gibt eine Funktion als Argument an. Wenn Sie sich die return-Anweisung in derselben Hierarchie ansehen, können Sie auch feststellen, dass sie eine Funktion namens Wrapper zurückgibt. Sie erhalten eine Funktion, verarbeiten sie (machen sie zu einem Wrapper) und geben sie zurück.

Definieren Sie Operationen, die getrennt von der Funktionsausführung ausgeführt werden sollen

Erstellen Sie als Nächstes ein Teil, das die zu gebende Funktion definiert. Im Beispielcode ist dies die Hierarchie des `def-Wrappers (* args, ** kwargs):`. In dieser Funktion wird zuerst die in der oberen Schicht empfangene Funktion ausgeführt. Ich möchte die func-Argumente nicht einschränken, daher verwende ich \ * args, \ * \ * kwargs als Argumente. Da Dekorateure für mehrere Funktionen arbeiten und ihren wahren Wert zeigen, verwenden sie häufig \ * args, \ * \ * kwargs als Argumente. Nachdem ich func ausgeführt habe, drucke ich die Argumente. Beachten Sie, dass \ * \ * kwargs seine Argumente als dikt speichert, sodass die Argumente in diktkonformer Sortierreihenfolge und nicht in der Reihenfolge vorliegen, in der sie beim Erstellen der Funktion erstellt wurden.

Wie benutzt man den Dekorateur?

Lassen Sie uns nach dem Erstellen des Dekorators die Funktion dekorieren. Der Dekorateur wird kurz vor der Funktionsdefinition mit einem at-Zeichen aufgerufen. Im Beispielcode seimei_deco.py wird der Dekorator print_args kurz vor der semei-Funktion von `` @ print_args``` aufgerufen. Die seimei-Funktion druckt jetzt zusätzlich zu ihrem ursprünglichen Verhalten "ihre Argumente nach Ausführung der Funktion".

Fügen wir einer Funktion, die sich vom obigen Beispiel unterscheidet, einen Dekorator hinzu. Es ist gut, dass Dekoratoren zu jeder Funktion hinzugefügt werden können. Ich denke, es ist besser, sie so zu erstellen, dass sie so universell wie möglich verwendet werden können, z. B. indem Sie \ * args, \ * \ * kwargs als Argumente angeben.

sum_deco.py


from print_args_decorator import print_args

@print_args
def sum_print_args(*args):
    return sum(args)

if __name__ == '__main__':
    sum_num = sum_print_args(1, 3)
    print('SUM = {0}'.format(sum_num))
<args is ...>
1
3
SUM = 4

Verwenden Sie functools.wraps

Wenn Sie einen Dekorator zum Generieren einer Funktion verwenden, gehen Informationen wie Dokumentzeichenfolgen verloren. Dies kann verhindert werden, indem beim Erstellen des Dekorators functools.wraps verwendet wird. Überprüfen wir die zuvor erstellte Dokumentzeichenfolge von `` `seimei_deeco.py```.

>>> from seimei_deco import seimei
>>> print(seimei.__doc__)
None

Die Dokumentzeichenfolge lautet Keine. Definieren wir den Dekorator mithilfe von functools.wraps neu und überprüfen die Dokumentzeichenfolge der generierten Funktion.

seimei_deco_use_functools.py


# -*- coding: utf-8 -*-
#Dekorateur zum Anzeigen von Argumenten
def print_args(func):
    import functools
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        res = func(*args, **kwargs)
        print('<args is ...>')
        for arg in args:
            print(arg)
        for kwarg in kwargs:
            print('{0}:{1}'.format(kwarg, kwargs[kwarg]))
        return res
    return wrapper

@print_args  #Dekorateur
def seimei(LastName, FirstName):
    """Zeigen Sie das Argument als Namen an"""
    print('Vollständiger Name:{0} {1}'.format(FirstName, LastName))

if __name__ == '__main__':
    seimei(LastName='Jackson', FirstName='Michael')
>>> from seimei_deco_use_functools import seimei
>>> print(seimei.__doc__)
Zeigen Sie das Argument als Namen an

Die Dokumentzeichenfolge der ursprünglichen Funktion wird angezeigt. Der Punkt hier ist, dass functools.wraps selbst als Dekorateur verwendet wird. (Ich habe auf [diese Seite] verwiesen (http://qiita.com/mtb_beta/items/d257519b018b8cd0cc2e)) Wie bereits erwähnt, sollten Dekorateure so erstellt werden, dass sie so weit wie möglich für allgemeine Zwecke verwendet werden können. Daher sollten grundsätzlich functools.wraps verwendet werden.

Wo zu verwenden

Dekorateure können an jede Funktion angeschlossen werden. Daher ist es effektiv, wenn dieselbe Operation wiederholt in __ Code __ ausgeführt wird. Sie können dieselbe Operation ausführen, indem Sie eine Funktion anstelle eines Dekorators erstellen und in der Funktionsdefinition einzeln aufrufen. Wenn Sie jedoch ein wenig vor der Funktionsdefinition eine Markierung schreiben, wird die Lesbarkeit des __- Codes verbessert. Kann angehoben werden __. Dies ist sehr nützlich, wenn Sie Fehlerprotokolle für jede Methode im Modul erfassen möchten.

Wenn ich mir den Code des Moduls ansehe, sehe ich manchmal einen Dekorateur namens @property. Dies ist eine Eigenschaft der Funktion, aber ich werde hier nicht auf Details eingehen. Weitere Informationen finden Sie auf dieser Seite.

Referenz

Recommended Posts

Ich kann dich nicht noch einmal fragen (?) Python Knowledge Series -Decorator-
Fibonacci-Sequenz (ich kann dich nicht noch einmal fragen)
Ich habe Python> Decorator ausprobiert
pyenv-vertualenv installiert die Python3-Serie nicht gut
Ich kann mich nicht an reguläre Python-Ausdrücke erinnern
Scikit-learn kann nicht in Python installiert werden
Ich kann Python-Skripte in Eclipse nicht debuggen
Ich schaute wieder auf die Python-Klasse zurück
Warum kann ich matplotlib nicht mit Python installieren? !!