English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Python Grundkurs

Python Prozesssteuerung

Python Funktion

Python Datentypen

Python 文件操作

O

Python Objekte und Klassen

Python Datum und Zeit

Python Fortgeschrittene Kenntnisse

Python Closure

Python Referenzhandbuch

In diesem Artikel werden Sie lernen, was ein Python-Closure ist, wie man ein Closure definiert und warum man Closure verwendet.

Nichtlokale Variablen in verschachtelten Funktionen

Eine Funktion, die in einer anderen Funktion definiert wird, wird als verschachtelte Funktion bezeichnet. Die verschachtelte Funktion kann auf die Variablen des geschlossenen Bereichs zugreifen.

In Python sind diese nichtlokalen Variablen standardmäßig schreibgeschützt und müssen als nichtlokal erklärt werden (verwendennonlocal Schlüsselwort)können geändert werden.

Hier ist ein Beispiel für eine verschachtelte Funktion, die nichtlokalen Variablen zugreift.

def print_msg(msg):
# Dies ist die äußere geschlossene Funktion
    def printer():
# Dies ist eine verschachtelte Funktion
        print(msg)
    printer()
# Wir führen diese Funktion aus
# Ausgabe: Hello
print_msg("Hello")

Wir können sehen, dass die verschachtelte Funktion printer() die nichtlokalen Variablen der geschlossenen Funktion zugreifen kannmsg.

Definition der geschlossenen Funktion

Was würde passieren, wenn die letzte Zeile der Funktion print_msg() nicht printer() aufgerufen, sondern zurückgegeben hat? Dies bedeutet, dass die Funktion wie folgt definiert ist.

def print_msg(msg):
# Dies ist die äußere geschlossene Funktion
    def printer():
# Dies ist eine verschachtelte Funktion
        print(msg)
    return printer # Das hat sich geändert
# Lassen Sie uns versuchen, diese Funktion aufzurufen.
# Ausgabe: Hello
another = print_msg("Hello")
another()

Das ist ungewöhnlich.

Die Funktion print_msg() wird mit einem String aufgerufen, "Hello" zurückgegebene Funktion gebunden anein weiteresName. Beim Aufruf von another(), obwohl wir die Ausführung der Funktion print_msg() beendet haben, erinnert sich die Nachricht immer noch daran.

Diese Technik, einige Daten ("Hello") an den Code anzuhängenin PythongenanntKlebrige Schicht.

Selbst wenn der Wert des Variablenbereichs außerhalb der Grenzen liegt oder die Funktion selbst aus dem aktuellen Namensraum gelöscht wurde, wird dieser Wert im geschlossenen Bereich noch erinnert.

Versuchen Sie, den folgenden Befehl im Python-Shell auszuführen, um die Ausgabe anzuzeigen.

>>> del print_msg
>>> another()
Hello
>>> print_msg("Hello")
Traceback (most recent call last):
...
NameError: name 'print_msg' is not defined

Welche Bedingungen müssen für Closure erfüllt sein?

Aus dem obigen Beispiel geht hervor, dass wir in Python eine Closure haben, wenn eine eingebettete Funktion einen Wert in ihrem geschlossenen Bereich referenziert.

Nachfolgend werden einige Bedingungen zusammengefasst, die erfüllt sein müssen, um Closure in Python zu erstellen.

  • Wir müssen eine eingebettete Funktion haben (Funktion innerhalb einer Funktion).

  • Die eingebettete Funktion muss auf Werte verweisen, die in der geschlossenen Funktion definiert wurden.

  • Die geschlossene Funktion muss eine eingebettete Funktion zurückgeben.

Wann sollte Closure verwendet werden?

Dann, was ist der Nutzen der Closure?

Closure können den Einsatz globaler Werte vermeiden und eine Form der Datenversteckung bieten. Sie können auch eine objektorientierte Lösung für dieses Problem bieten.

Wenn Methoden in einer Klasse selten implementiert werden (meistens nur eine Methode) können Closure eine elegantere Alternative bieten. Aber wenn die Anzahl der Attribute und Methoden zunimmt, ist es besser, eine Klasse zu implementieren.

Dies ist ein einfaches Beispiel, bei dem Closure möglicherweise attraktiver ist als die Definition von Klassen und die Erstellung von Objekten.

def make_multiplier_of(n):
    def multiplier(x):
        return x * n
    return multiplier
# 3der Multiplikator
times3 = make_multiplier_of(3)
# 5der Multiplikator
times5 = make_multiplier_of(5)
# Ausgabe: 27
print(times3(9))
# Ausgabe: 15
print(times5(3))
# Ausgabe: 30
print(times5(times3(2))

Python-Dekoratoren auchEs wird viel mit Closure gearbeitet.

Abschließend sei darauf hingewiesen, dass man die Werte in geschlossenen Funktionen finden kann.

Alle Funktionsobjekte haben eine __closure__-Eigenschaft. Wenn es eine Closure-Funktion ist, gibt diese Eigenschaft ein Tupel von Zellelementen zurück. Siehe上面的示例,我们知道times3und times5Es ist eine Closure-Funktion.

>>> make_multiplier_of.__closure__
>>> times3__closure__
(<cell at 0x0000000002D155B8: int object at 0x000000001E39B6E0>,)

Der Zellelement hat die Eigenschaft cell_contents, um geschlossene Werte zu speichern.

>>> times3__closure__[0].cell_contents
3
>>> times5__closure__[0].cell_contents
5