Python Closures: Wie benutzt man es und warum?

In diesem Tutorial erfahren Sie mehr über den Python-Abschluss, das Definieren eines Abschlusses und die Gründe, warum Sie ihn verwenden sollten.

Nichtlokale Variable in einer verschachtelten Funktion

Bevor wir uns mit einem Abschluss befassen, müssen wir zunächst verstehen, was eine verschachtelte Funktion und eine nichtlokale Variable ist.

Eine in einer anderen Funktion definierte Funktion wird als verschachtelte Funktion bezeichnet. Verschachtelte Funktionen können auf Variablen des umschließenden Bereichs zugreifen.

In Python sind diese nicht lokalen Variablen standardmäßig schreibgeschützt, und wir müssen sie explizit als nicht lokal deklarieren (unter Verwendung eines nicht lokalen Schlüsselworts), um sie zu ändern.

Das folgende Beispiel zeigt eine verschachtelte Funktion, die auf eine nicht lokale Variable zugreift.

 def print_msg(msg): # This is the outer enclosing function def printer(): # This is the nested function print(msg) printer() # We execute the function # Output: Hello print_msg("Hello")

Ausgabe

 Hallo

Wir können sehen, dass die verschachtelte printer()Funktion auf die nicht lokale msg-Variable der einschließenden Funktion zugreifen konnte.

Schließen einer Schließfunktion

Was würde im obigen Beispiel passieren, wenn die letzte Zeile der Funktion print_msg()die printer()Funktion zurückgeben würde, anstatt sie aufzurufen? Dies bedeutet, dass die Funktion wie folgt definiert wurde:

 def print_msg(msg): # This is the outer enclosing function def printer(): # This is the nested function print(msg) return printer # returns the nested function # Now let's try calling this function. # Output: Hello another = print_msg("Hello") another()

Ausgabe

 Hallo

Das ist unüblich.

Die print_msg()Funktion wurde mit der Zeichenfolge aufgerufen "Hello"und die zurückgegebene Funktion an den Namen einer anderen gebunden. Beim Aufruf another()wurde die Nachricht immer noch gespeichert, obwohl wir die Ausführung der print_msg()Funktion bereits beendet hatten .

Diese Technik, mit der einige Daten ( "Helloin diesem Fall) an den Code angehängt werden, wird in Python als Closure bezeichnet .

Dieser Wert im umschließenden Bereich wird auch dann gespeichert, wenn die Variable den Bereich verlässt oder die Funktion selbst aus dem aktuellen Namespace entfernt wird.

Führen Sie die folgenden Schritte in der Python-Shell aus, um die Ausgabe anzuzeigen.

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

Hier funktioniert die zurückgegebene Funktion auch dann noch, wenn die ursprüngliche Funktion gelöscht wurde.

Wann haben wir Schließungen?

Wie aus dem obigen Beispiel hervorgeht, haben wir in Python einen Abschluss, wenn eine verschachtelte Funktion auf einen Wert in ihrem umschließenden Bereich verweist.

Die Kriterien, die erfüllt sein müssen, um einen Abschluss in Python zu erstellen, werden in den folgenden Punkten zusammengefasst.

  • Wir müssen eine verschachtelte Funktion haben (Funktion innerhalb einer Funktion).
  • Die verschachtelte Funktion muss sich auf einen Wert beziehen, der in der umschließenden Funktion definiert ist.
  • Die umschließende Funktion muss die verschachtelte Funktion zurückgeben.

Wann sind Verschlüsse zu verwenden?

Wofür sind Verschlüsse gut?

Durch das Schließen können globale Werte vermieden und Daten ausgeblendet werden. Es kann auch eine objektorientierte Lösung für das Problem bieten.

Wenn in einer Klasse nur wenige Methoden (in den meisten Fällen eine Methode) implementiert werden müssen, können Abschlüsse eine alternative und elegantere Lösung darstellen. Wenn die Anzahl der Attribute und Methoden jedoch größer wird, ist es besser, eine Klasse zu implementieren.

Hier ist ein einfaches Beispiel, bei dem ein Abschluss möglicherweise vorzuziehen ist, als eine Klasse zu definieren und Objekte zu erstellen. Aber die Präferenz liegt ganz bei Ihnen.

 def make_multiplier_of(n): def multiplier(x): return x * n return multiplier # Multiplier of 3 times3 = make_multiplier_of(3) # Multiplier of 5 times5 = make_multiplier_of(5) # Output: 27 print(times3(9)) # Output: 15 print(times5(3)) # Output: 30 print(times5(times3(2)))

Ausgabe

 27 15 30

Python-Dekorateure verwenden auch Verschlüsse in großem Umfang.

Abschließend sei darauf hingewiesen, dass die Werte, die in der Schließfunktion enthalten sind, herausgefunden werden können.

Alle Funktionsobjekte haben ein __closure__Attribut, das ein Tupel von Zellenobjekten zurückgibt, wenn es sich um eine Abschlussfunktion handelt. In Bezug auf das obige Beispiel kennen times3und times5sind wir Schließfunktionen.

 >>> make_multiplier_of.__closure__ >>> times3.__closure__ (,)

Das Zellenobjekt hat das Attribut cell_contents, in dem der geschlossene Wert gespeichert ist.

 >>> times3.__closure__(0).cell_contents 3 >>> times5.__closure__(0).cell_contents 5

Interessante Beiträge...