[PYTHON] Wie benutzt man den Dekorateur?

Ich verstehe, wie man einen Dekorateur schreibt.

Wie der Name schon sagt, ist ein Dekorateur ein Dekorateur. Was Sie dekorieren, ist eine Funktion, eine Funktion. Eine andere Methode.

Ich verstehe. Es ist schwer. Ich verstehe den Dekorateur.

Murmelte Takeshi und rannte los, als wäre er umgedreht worden. Aber das Signal begann zu blinken und hörte auf. Ja, er folgt den Verkehrsregeln.

Und denken Sie daran, die Zeit zu verlassen.

Die Menschheit ist das, was ich nutzen möchte, wenn ich schreiben kann. Wenn ich es jedoch tatsächlich verwenden möchte, weiß ich nicht, wo ich es verwenden soll. Ich kann mir keine effektive Verwendung vorstellen.

So eine Person.

Ja! Ich weiß es nicht einmal!

Nein, aber vielleicht habe ich ein wenig verstanden.

Warum Dekorateure verwenden?

Warum einen Dekorateur benutzen?

Mir fällt so etwas ein. Dies wird oft als Vorteil der Verwendung erwähnt.

Das ist nichts falsch! Überwiegend richtig! Oh, ich bin sicher, dass es richtig ist!

Aber ich weiß nur nicht, wo ich es verwenden soll.

Weil es aus den oben genannten Gründen viele andere Möglichkeiten gibt, oder? Gibt es zum Beispiel Vererbung? Ist es in Ordnung, es so zu machen, wie es ist? Du bist daran gewöhnt, oder? Ich möchte nicht die Mühe machen, so etwas wie einen Dekorateur zu schreiben. Ich denke schon, aber beschweren Sie sich?

Denkst du? Denkst du nicht? Ich denke.

Warum also einen Dekorateur wagen?

Um darüber nachzudenken, müssen wir auf die ** Bedeutung ** der Verarbeitung des Codes achten. Das Fazit ist, dass wir Dekoratoren für die ** Trennung der Geschäftslogik ** verwenden.

Trennung der Geschäftslogik

Dekorateur, der Funktionsaufrufe verfolgt

Möglicherweise haben Sie ein Beispiel wie dieses als ersten Schritt beim Dekorieren gesehen.

from functools import wraps

def trace_func_call(func):
    @wraps(func)
    def wrapper(*arg):
        print(func.__name__ + ' is called.')
        return func(*arg)
    return wrapper

@trace_func_call
def spam(s):
    print((s + '!') * 5)

@trace_func_call
def ham(s):
    print((s + '?') * 5)

spam('egg')
ham('sausage')

** Ausführungsergebnis **

spam is called.
egg!egg!egg!egg!egg!
ham is called.
sausage?sausage?sausage?sausage?sausage?

Ein Dekorateur, der es bei jedem Aufruf einer Funktion anzeigt.

Zu diesem Zeitpunkt ist die Rolle des Dekorateurs keine Geschäftslogik, nicht wahr? Das Beispiel ist sehr gut geeignet, aber die Verarbeitung, die Sie als Geschäftslogik ausführen möchten, ist die Verarbeitung der Funktionen "Spam" und "Ham", nicht wahr? Es ist ein beschissener Typ, der 5 Mal mit "!" Oder "?" Wiederholt. Als Argument.

Zu diesem Zeitpunkt ist das Anzeigen des Funktionsaufrufs nicht die Geschäftslogik, sondern die zu implementierende Logik, da sie für die Verwaltung erforderlich ist. Ihre Logik ist semantisch anders.

Sie können Dekoratoren verwenden, um die Verwaltungslogik von der Geschäftslogik zu trennen. Mit anderen Worten, basierend auf dem, was Sie tun möchten, sind Dekorateure diejenigen, die die Absicht erkennen, die Geschäftslogik, die der Hauptzweck des Codes ist, auf saubere Weise von der Verwaltungslogik zu trennen. Natürlich möchte ich nicht sagen, dass dies die einzige Rolle des Dekorateurs ist, aber es gibt einen großartigen Vorschlag zur Verwendung des Dekorateurs.

Bargelddekorateur

Weiter ist etwas praktischer. Dies ist ein Beispieldekorateur aus Raymond Hettingers Vortrag ** "Code in schönes, idiomatisches Python verwandeln" ** auf der PyCon US 2013.

Beginnen wir mit dem ursprünglichen "weniger wünschenswerten" Code.

def web_lookup(url, saved={}):
    if url in saved:
        return saved[url]
    page = urllib.urlopen(url).read()
    saved[url] = page
    return page

Klicken Sie hier, um eine bessere Version des obigen Codes mit einem Dekorateur zu erhalten.

def cache(func):
    saved = {}
    @wraps(func)
    def newfunc(*args):
        if args in saved:
            return saved[args]
        result = func(*args)
        saved[args] = result
        return result
    return newfunc

@cache
def web_lookup(url):
    return urllib.urlopen(url).read()

Die Funktion "web_lookup" ist eine Funktion zum Abrufen der Webseite der angegebenen URL. Zu diesem Zeitpunkt hat es eine Funktion zum Zwischenspeichern der erfassten Seiten.

Es ist ein sehr kurzer Code, aber Sie können sehen, dass die Funktionalität dieses Codes semantisch wie folgt unterteilt ist:

--Geschäftslogik -> Ruft die Webseite der angegebenen URL ab

Im ursprünglichen Code wird die Caching-Funktionalität durch ein Wörterbuch von Argumenten bereitgestellt, die an die Funktion "web_lookup" übergeben werden. Mit anderen Worten, die Funktion selbst ist eine Implementierung, die die Funktionalität von Geschäftslogik und Verwaltungslogik beinhaltet.

Im Gegensatz dazu implementiert die Funktion in besserem Code nur die Geschäftslogik, und die Verwaltungslogik wird vom geschlossenen Dekorateur implementiert. Auf diese Weise werden Sie feststellen, dass die Geschäftslogik klar getrennt ist und der Code besser lesbar und wartbar ist.

Die Menge an Code hat mit der Implementierung von Dekorateuren zugenommen, aber ich denke, dass es ein sehr pythonisches Gefühl ist, ihn "schönen Code" zu nennen.

Übrigens sind diese Cash Decorator-Muster Standardmuster, daher ist es nicht schwierig und Sie sollten es auf jeden Fall versuchen.

Übrigens denke ich, dass der Code der Folie der von mir zitierten Vorlesung falsch ist ... Also ändere ich den Code, den ich oben geschrieben habe. Dies ist der Dekorateur. Du liegst falsch, richtig? https://speakerdeck.com/pyconslides/transforming-code-into-beautiful-idiomatic-python-by-raymond-hettinger-1

Ein weiteres einfaches Beispiel

Dann noch einer.

Besonders wenn 2.x verwendet wird und der Zeichencode der Eingabe unbekannt ist, bin ich es wirklich leid, mit der Zeichenfolge umzugehen, irgendwie zu dekodieren, irgendwie uni-kodo usw., also verwende ich bei der internen Verarbeitung Chardet mit einem Dekorateur Lassen Sie uns alles Unicode machen und verarbeiten.

Dies kann beim Schreiben eines kleinen Werkzeugs hilfreich sein.

import chardet

def unicode_conv(func):
    def wrapper(*args):
        f = lambda x: x.decode(chardet.detect(x)['encoding'])
        args = [f(arg) if type(arg) != unicode else arg for arg in args]
        return func(*args)
    return wrapper

def funcA(*args):
    for arg in args:
        print(repr(arg))

@unicode_conv
def funcB(*args):
    for arg in args:
        print(repr(arg))

funcA('shrubbery')
funcB('shrubbery')
funcB(u'shrubbery')

** Ausführungsergebnis **

'shrubbery'
u'shrubbery'
u'shrubbery'

Recommended Posts

Wie benutzt man den Dekorateur?
Verwendung der Zip-Funktion
Verwendung des optparse-Moduls
Verwendung des ConfigParser-Moduls
Verwendung von xml.etree.ElementTree
Wie benutzt man Python-Shell
Hinweise zur Verwendung von tf.data
Verwendung von virtualenv
Verwendung der Spark ML-Pipeline
Wie benutzt man Seaboan?
Verwendung von Image-Match
Verwendung von Pandas 2
Verwendung von Virtualenv
Verwendung von pytest_report_header
[Linux] Verwendung des Befehls echo
Wie man Bio.Phylo benutzt
Verwendung von SymPy
Wie man x-means benutzt
Verwendung von WikiExtractor.py
Verwendung von IPython
Verwendung von virtualenv
Wie benutzt man Matplotlib?
Verwendung von iptables
Wie benutzt man numpy?
Verwendung von TokyoTechFes2015
Wie benutzt man venv
Verwendung des Wörterbuchs {}
Wie benutzt man Pyenv?
Wie man Python-Kabusapi benutzt
Verwendung des IPython-Debuggers (ipdb)
Verwendung von return
Wie man Imutils benutzt
Verwendung der C-Bibliothek in Python
So verwenden Sie MkDocs zum ersten Mal
Verwendung der Grafikzeichnungsbibliothek Bokeh
Verwendung der Google Cloud Translation API
Verwendung der NHK-Programmführer-API
[Algorithmus x Python] Verwendung der Liste
Verwendung von Qt Designer
Verwendung der Suche sortiert
[gensim] Verwendung von Doc2Vec
python3: Verwendung der Flasche (2)
Verstehen Sie, wie man Django-Filter verwendet
[Python] Verwendung von Liste 1
Verwendung von FastAPI ③ OpenAPI
Verwendung von IPython Notebook
Wie man Pandas Rolling benutzt
[Hinweis] Verwendung von virtualenv
Python: Wie man pydub benutzt
[Python] Verwendung von checkio
So bedienen Sie GeoIp2 von Django
[Python] Verwendung von input ()
[Einführung] Verwendung von open3d
Wie benutzt man Python Lambda?
So verwenden Sie Jupyter Notebook
[Python] Verwendung von virtualenv
python3: Verwendung der Flasche (3)