[PYTHON] Funktionen und Dekorateure höherer Ordnung

Beschreibt Funktionen höherer Ordnung, bei denen es sich um eine etwas größere Version von Funktionen handelt, sowie die Dekorationsnotation von Python.

Funktion

Wenn es eine Menge A und eine Menge B gibt, wird die Regel "f", die das Element "f (a)" der Menge B für jedes Element "a" der Menge A eindeutig bestimmt, als Funktion von A nach B bezeichnet.

Stellen Sie sich eine Funktion times2 vor, die ihre Argumente verdoppelt und zurückgibt

def times2(i):
    return i * 2

Wenn zu diesem Zeitpunkt 0, 1, 2 als "i" angegeben wird,

Und eine Funktion von set ([0,1,2]) zu einer Menge von ganzen Zahlen wird definiert.

times2.png

Funktionen in der Programmierung

Funktionen haben folgende Auswirkungen auf die Programmierung:

Durch Beherrschen der unten erläuterten Funktionen höherer Ordnung gibt es mehr Situationen, in denen diese Effekte erzielt werden können.

Funktion als Argument

Stellen Sie sich vor, Sie wenden denselben Wert 1 auf die Funktionen an, die das Argument mit 0 multiplizieren, mit 1 multiplizieren und die Argumente verdoppeln.

Verglichen mit der Definition der Funktion times2: set ([0, 1, 2]) -> Int wird die Korrespondenzregel von der Menge der Funktionen set ([times0, times1, times2]) zur Menge der Ganzzahlen Ich kann es sehen.

apply1.png

apply1 kann wie folgt implementiert werden

def apply1(f):
    return f(1)

Eine Funktion, die eine Funktion als Argument verwendet (oder eine Funktion, die eine Funktion zurückgibt, wie im nächsten Abschnitt gezeigt), wird als Funktion höherer Ordnung bezeichnet.

Funktion als Rückgabewert

Funktion höherer Ordnung, die eine Zahl als Argument verwendet und eine Funktion zurückgibt

def times_n(n):
    def f(i):
        return n * i
    return f

Wenn Sie verwenden, können Sie die zuvor veröffentlichten "times0", "times1", "times2" verwenden.

times0 = times_n(0)
times1 = times_n(1)
times2 = times_n(2)

Kann definiert werden als.

times_n.png

>>> apply1(times0)
0
>>> apply1(times1)
1
>>> apply1(times2)
2

Funktionen von einer Reihe von Funktionen zu einer Reihe von Funktionen

Wenn Sie eine Funktion höherer Ordnung verwenden, die eine Funktion als Argument verwendet und die Funktion zurückgibt

Usw. kann in wiederverwendbarer Form geschrieben werden.

def dot(g):
    "f -> g . f"
    def func(f):
        def composite(i):
            return g(f(i))
        return composite
    return func
>>> (lambda i: i*2)((lambda i: i+5)(1))
12
>>> f = dot(lambda i: i*2)(lambda i: i+5)
>>> f(1)
12

Dekorationsnotation

Wenn es eine Funktion höherer Ordnung "Dekorator" gibt, die eine Funktion als Argument verwendet und die Funktion zurückgibt

@decorator
def function(argument):
    # ...

Ersetzt function durch decorator (function).

Dekorateur Beispiel

Schreiben Sie einen Dekorateur, der ein Protokoll von Funktionsaufrufen druckt, und wenden Sie es auf ineffiziente rekursive Funktionen an.

def trace(function):
    "Dekorateur zum Drucken des Anrufprotokolls"
    def inner(*args):
        "Anrufprotokolle vor und nach der Funktion drucken"
        print("{0}{1}".format(function.__name__, args))
        ret = function(*args)
        print("{0}{1} ==> {2}".format(function.__name__, args, ret))
        return ret
    return inner


@trace
def fib(n):
    "Finden Sie die Fibonacci-Nummer"
    if n == 0:
        return 0
    if n == 1:
        return 1
    return fib(n-2) + fib(n-1)

Sie können sehen, dass dieselbe Berechnung viele Male durchgeführt wurde.

% python3 -c 'import fib; fib.fib(4)'
fib(4,)
fib(2,)
fib(0,)
fib(0,) ==> 0
fib(1,)
fib(1,) ==> 1
fib(2,) ==> 1
fib(3,)
fib(1,)
fib(1,) ==> 1
fib(2,)
fib(0,)
fib(0,) ==> 0
fib(1,)
fib(1,) ==> 1
fib(2,) ==> 1
fib(3,) ==> 2
fib(4,) ==> 3

TIPPS: Attributvererbung

Im vorherigen Beispiel wäre das Dokument von "fib" und der Funktionsname das von "inner".

>>> fib.__doc__
'Anrufprotokolle vor und nach der Funktion drucken'
>>> fib.__name__
'inner'

→ Es ist schmerzhaft, wenn Sie denselben Dekorateur auf mehrere Funktionen anwenden

from functools import wraps


def trace(function):
    "Dekorateur zum Drucken des Anrufprotokolls"
    @wraps(function)
    def inner(*args):
        "Anrufprotokolle vor und nach der Funktion drucken"
    ...

Wenn du gehst

>>> fib.__doc__
'Finden Sie die Fibonacci-Nummer'
>>> fib.__name__
'fib'

Und erbt die Dokumentzeichenfolge und den Namen der ursprünglichen Funktion. Nützlich beim Anzeigen von Stapelspuren

TIPPS: * args und ** kwargs

Sie können vielseitigere Dekorateure mit * args und ** kwargs schreiben.

TIPPS: Nicht ersetzen

Dekorateure müssen nicht unbedingt eine Funktion durch eine neue ersetzen. Zum Beispiel

Usw. sind ebenfalls möglich.

Zusammenfassung

Recommended Posts

Funktionen und Dekorateure höherer Ordnung
Funktionen höherer Ordnung und Einschlussnotation in Python
Anonyme Funktion und Kartenfunktion
Python 3 Sortier- und Vergleichsfunktionen
Klassenvererbung und Superfunktion
Vergleich der Verwendung von Funktionen höherer Ordnung in Python 2 und 3
Über Python-Diktat und sortierte Funktionen
Formeln und Funktionen (entsprechend aktualisiert)
[Python] Was sind @classmethod und Dekorateure?
GCP: Link-Funktionen und Pub / Sub
Verstehe die Regeln und konvexen Funktionen von Armijo
Tipps zum Ersetzen und Debuggen von Funktionen
Zeichnen Sie Dreiecksfunktionen mit Numpy und Matplotlib
Protokollausgabe der Google Cloud-Funktionen (und süchtig)
Verwenden Sie Python und MeCab mit Azure-Funktionen
Korrespondenz zwischen den in Python integrierten Funktionen und Rust