3.1 Einführung in Closures
Ein Closure ist eine Funktion, die Variablen aus ihrem umgebenden Gültigkeitsbereich erfasst, selbst nachdem dieser Gültigkeitsbereich abgeschlossen ist. Das bedeutet, dass ein Closure sich an die Werte von Variablen aus seinem äußeren Gültigkeitsbereich „erinnern“ kann und weiterhin mit ihnen arbeiten kann, selbst wenn dieser Bereich nicht mehr aktiv ist.
Um zu verstehen, wie Closures funktionieren, schauen wir uns das folgende Beispiel an:
def outer_function(x):
def inner_function(y):
return x + y
return inner_function
closure = outer_function(10)
print(closure(5)) # Ausgabe: 15
Schauen wir uns an, was hier passiert:
Äußere Funktion (outer_function): Diese Funktion nimmt das Argument x und definiert eine innere Funktion inner_function, die das Argument y nimmt und die Summe von x und y zurückgibt. Die Funktion inner_function wird nicht innerhalb von outer_function aufgerufen, sondern nur deklariert.
Innere Funktion (inner_function): Diese Funktion wird aus outer_function zurückgegeben und behält intern einen Verweis auf den Wert x, der an outer_function übergeben wurde.
Closure: Die Variable closure wird zu einem Closure, das sich an den Wert von x (in diesem Fall 10) „erinnert“ und diesen bei einem Aufruf verwenden kann.
Normalerweise kann niemand beim ersten Mal mit Closures richtig umgehen. Also lasst uns euer Verständnis für Closures anhand von Beispielen verbessern.
3.2 Beispiele für die Verwendung von Closures
Erstellung einer Generatorfunktion
Closures können verwendet werden, um Generatorfunktionen zu erstellen, die Wertfolgen erzeugen.
def make_counter():
count = 0
def counter():
nonlocal count
count += 1
return count
return counter
counter = make_counter()
print(counter()) # Ausgabe: 1
print(counter()) # Ausgabe: 2
print(counter()) # Ausgabe: 3
Erklärung:
Generatorfunktion (make_counter): Diese Funktion erstellt die Variable count und gibt die innere Funktion counter zurück, die den Wert von count erhöht und zurückgibt.
Closure: Die Funktion counter behält den Zustand der Variable count und kann diesen bei jedem Aufruf ändern.
Erstellung einer Funktion mit Konfiguration
Closures können verwendet werden, um Funktionen mit einer vorab definierten Konfiguration zu erstellen.
def make_multiplier(factor):
def multiplier(x):
return x * factor
return multiplier
double = make_multiplier(2)
triple = make_multiplier(3)
print(double(5)) # Ausgabe: 10
print(triple(5)) # Ausgabe: 15
Erklärung:
Konfigurationsfunktion (make_multiplier): Diese Funktion nimmt einen Faktor factor und gibt eine innere Funktion multiplier zurück, die den Eingabewert mit factor multipliziert.
Closures: Die Funktionen double und triple sind Closures, die ihre eigenen Werte für factor speichern und diese für die Multiplikation verwenden.
Datenfilterung mit Parametern
Closures können nützlich sein, um Filterfunktionen mit Parametern zu erstellen.
def make_filter(threshold):
def filter_func(value):
return value > threshold
return filter_func
filter_above_10 = make_filter(10)
data = [5, 10, 15, 20]
filtered_data = list(filter(filter_above_10, data))
print(filtered_data) # Ausgabe: [15, 20]
Erklärung:
Filterfunktion (make_filter): Diese Funktion nimmt einen Schwellenwert threshold und gibt eine innere Funktion filter_func zurück, die prüft, ob ein Wert den Schwellenwert überschreitet.
Closure: Die Funktion filter_func speichert den Wert von threshold und verwendet diesen zur Filterung der Daten.
3.3 Vorteile und Nachteile von Closures
Vorteile der Verwendung von Closures
Kapselung von Zustand: Closures ermöglichen es, den Zustand innerhalb von Funktionen zu kapseln, globale Variablen zu vermeiden und die Lesbarkeit sowie Wartbarkeit des Codes zu verbessern.
Flexibilität: Closures können verwendet werden, um Funktionen mit spezifischer Konfiguration oder Verhalten zu erstellen, was den Code flexibler und anpassungsfähiger macht.
Funktionale Programmierung: Closures sind ein wichtiger Bestandteil der funktionalen Programmierung, die es ermöglicht, höherwertige Funktionen und andere funktionale Konstrukte zu schaffen.
Einschränkungen und mögliche Probleme
Obwohl Closures viele Vorteile bieten, gibt es auch Einschränkungen:
Speichernutzung: Closures können Verweise auf Objekte aufbewahren, die nicht mehr verwendet werden, was zu Speicherlecks führen kann.
Komplexität beim Debuggen: Closures können das Debuggen des Codes erschweren, da die Zustände der Variablen nicht immer offensichtlich sind.
GO TO FULL VERSION