Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> Python

Python-Dekorateure

Python-Dekoratoren

Ein Dekorateur nimmt eine Funktion auf, fügt einige Funktionen hinzu und gibt sie zurück. In diesem Tutorial erfahren Sie, wie Sie einen Decorator erstellen und warum Sie ihn verwenden sollten.

Video:@Decorators in Python

Dekorateure in Python

Python hat ein interessantes Feature namens Decorators um Funktionalität zu einem bestehenden Code hinzuzufügen.

Dies wird auch Metaprogrammierung genannt weil ein Teil des Programms versucht, einen anderen Teil des Programms zur Kompilierzeit zu modifizieren.


Voraussetzungen für das Erlernen von Dekorateuren

Um Decorators zu verstehen, müssen wir zuerst ein paar grundlegende Dinge in Python wissen.

Wir müssen uns damit abfinden, dass alles in Python (ja! sogar Klassen) Objekte sind. Namen, die wir definieren, sind einfach Bezeichner, die an diese Objekte gebunden sind. Funktionen sind keine Ausnahmen, sie sind auch Objekte (mit Attributen). An dasselbe Funktionsobjekt können verschiedene Namen gebunden werden.

Hier ist ein Beispiel.

def first(msg):
    print(msg)


first("Hello")

second = first
second("Hello")

Ausgabe

Hello
Hello

Wenn Sie den Code ausführen, funktionieren beide first und second die gleiche Ausgabe geben. Hier die Namen first und second beziehen sich auf dasselbe Funktionsobjekt.

Jetzt werden die Dinge seltsamer.

Funktionen können als Argumente an eine andere Funktion übergeben werden.

Wenn Sie Funktionen wie map verwendet haben , filter und reduce in Python, dann wissen Sie bereits Bescheid.

Solche Funktionen, die andere Funktionen als Argumente annehmen, werden auch als Funktionen höherer Ordnung bezeichnet . Hier ist ein Beispiel für eine solche Funktion.

def inc(x):
    return x + 1


def dec(x):
    return x - 1


def operate(func, x):
    result = func(x)
    return result

Wir rufen die Funktion wie folgt auf.

>>> operate(inc,3)
4
>>> operate(dec,3)
2

Außerdem kann eine Funktion eine andere Funktion zurückgeben.

def is_called():
    def is_returned():
        print("Hello")
    return is_returned


new = is_called()

# Outputs "Hello"
new()

Ausgabe

Hello

Hier, is_returned() ist eine verschachtelte Funktion, die bei jedem Aufruf von is_called() definiert und zurückgegeben wird .

Schließlich müssen wir Closures in Python kennen.


Zurück zu Dekorateuren

Funktionen und Methoden werden aufrufbar genannt wie sie genannt werden können.

Eigentlich jedes Objekt, das den speziellen __call__() implementiert Methode wird als aufrufbar bezeichnet. Im einfachsten Sinne ist ein Decorator also ein Callable, das ein Callable zurückgibt.

Grundsätzlich nimmt ein Dekorateur eine Funktion auf, fügt einige Funktionen hinzu und gibt sie zurück.

def make_pretty(func):
    def inner():
        print("I got decorated")
        func()
    return inner


def ordinary():
    print("I am ordinary")

Wenn Sie die folgenden Codes in der Shell ausführen,

>>> ordinary()
I am ordinary

>>> # let's decorate this ordinary function
>>> pretty = make_pretty(ordinary)
>>> pretty()
I got decorated
I am ordinary

Im oben gezeigten Beispiel make_pretty() ist Dekorateur. Im Zuweisungsschritt:

pretty = make_pretty(ordinary)

Die Funktion ordinary() dekoriert und die zurückgegebene Funktion erhielt den Namen pretty .

Wir können sehen, dass die Decorator-Funktion der ursprünglichen Funktion einige neue Funktionen hinzugefügt hat. Dies ist vergleichbar mit dem Verpacken eines Geschenks. Der Decorator fungiert als Wrapper. Die Art des dekorierten Objekts (das eigentliche Geschenk im Inneren) ändert sich nicht. Aber jetzt sieht es hübsch aus (seitdem es dekoriert wurde).

Im Allgemeinen dekorieren wir eine Funktion und weisen sie neu zu,

ordinary = make_pretty(ordinary).

Dies ist ein gängiges Konstrukt und aus diesem Grund hat Python eine Syntax, um dies zu vereinfachen.

Wir können den @ verwenden zusammen mit dem Namen der Decorator-Funktion und platzieren Sie es über der Definition der zu dekorierenden Funktion. Zum Beispiel

@make_pretty
def ordinary():
    print("I am ordinary")

entspricht

def ordinary():
    print("I am ordinary")
ordinary = make_pretty(ordinary)

Dies ist nur ein syntaktischer Zucker, um Dekorateure zu implementieren.


Funktionen mit Parametern dekorieren

Der obige Decorator war einfach und funktionierte nur mit Funktionen, die keine Parameter hatten. Was wäre, wenn wir Funktionen hätten, die Parameter annehmen wie:

def divide(a, b):
    return a/b

Diese Funktion hat zwei Parameter, a und b . Wir wissen, dass es einen Fehler geben wird, wenn wir b übergeben als 0.

>>> divide(2,5)
0.4
>>> divide(2,0)
Traceback (most recent call last):
...
ZeroDivisionError: division by zero

Lassen Sie uns nun einen Decorator erstellen, der diesen Fall prüft, der den Fehler verursacht.

def smart_divide(func):
    def inner(a, b):
        print("I am going to divide", a, "and", b)
        if b == 0:
            print("Whoops! cannot divide")
            return

        return func(a, b)
    return inner


@smart_divide
def divide(a, b):
    print(a/b)

Diese neue Implementierung gibt None zurück wenn die Fehlerbedingung auftritt.

>>> divide(2,5)
I am going to divide 2 and 5
0.4

>>> divide(2,0)
I am going to divide 2 and 0
Whoops! cannot divide

Auf diese Weise können wir Funktionen dekorieren, die Parameter annehmen.

Ein aufmerksamer Beobachter wird feststellen, dass die Parameter des verschachtelten inner() Die Funktion innerhalb des Dekorators ist identisch mit den Parametern der Funktionen, die sie dekoriert. Unter Berücksichtigung dessen können wir jetzt allgemeine Dekorateure erstellen, die mit einer beliebigen Anzahl von Parametern arbeiten.

In Python wird diese Magie als function(*args, **kwargs) ausgeführt . Auf diese Weise args wird das Tupel aus Positionsargumenten und kwargs sein wird das Wörterbuch der Schlüsselwortargumente sein. Ein Beispiel für einen solchen Dekorierer ist:

def works_for_all(func):
    def inner(*args, **kwargs):
        print("I can decorate any function")
        return func(*args, **kwargs)
    return inner

Verketten von Dekorateuren in Python

Mehrere Decorators können in Python verkettet werden.

Das heißt, eine Funktion kann mehrfach mit unterschiedlichen (oder gleichen) Dekorateuren dekoriert werden. Wir platzieren die Dekoratoren einfach über der gewünschten Funktion.

def star(func):
    def inner(*args, **kwargs):
        print("*" * 30)
        func(*args, **kwargs)
        print("*" * 30)
    return inner


def percent(func):
    def inner(*args, **kwargs):
        print("%" * 30)
        func(*args, **kwargs)
        print("%" * 30)
    return inner


@star
@percent
def printer(msg):
    print(msg)


printer("Hello")

Ausgabe

******************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Hello
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
******************************

Die obige Syntax von,

@star
@percent
def printer(msg):
    print(msg)

entspricht

def printer(msg):
    print(msg)
printer = star(percent(printer))

Die Reihenfolge, in der wir Dekorateure verketten, spielt eine Rolle. Wenn wir die Reihenfolge umgekehrt hätten als,

@percent
@star
def printer(msg):
    print(msg)

Die Ausgabe wäre:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
******************************
Hello
******************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Python

  1. Python-Datentypen
  2. Python-Operatoren
  3. Python-pass-Anweisung
  4. Python-Funktionsargumente
  5. Anonyme Python/Lambda-Funktion
  6. Python-Lambda-Funktionen mit BEISPIELE
  7. Python abs() Funktion:Beispiele für absolute Werte
  8. Python-Funktion round() mit BEISPIELE
  9. Python range() Funktion:Float, List, For-Schleife Beispiele
  10. Python map() Funktion mit BEISPIELE