In Python ist ein Abschluss eine Instanz einer Funktion, an die Variablen unveränderlich gebunden sind.
Tatsächlich erklärt das Datenmodell dies in seiner Beschreibung des Funktionsattributs __closure__
:
Keine oder ein Tupel von Zellen , die Bindungen für die freien Variablen der Funktion enthalten. Schreibgeschützt
Um dies zu demonstrieren:
def enclosure(foo):
def closure(bar):
print(foo, bar)
return closure
closure_instance = enclosure('foo')
Es ist klar, dass wir jetzt eine Funktion haben, auf die der Variablenname zeigt closure_instance
. Wenn wir es mit einem Objekt aufrufen, sollte es angeblich bar
die Zeichenfolge drucken 'foo'
und unabhängig von der Zeichenfolgendarstellung bar
.
In der Tat, die Zeichenfolge ‚foo‘ wird auf die Instanz der Funktion gebunden, und wir können es direkt hier lesen, indem Sie den Zugriff auf cell_contents
Attribut des ersten (und einzigen) Zelle in dem Tupel des __closure__
Attributs:
>>> closure_instance.__closure__[0].cell_contents
'foo'
Nebenbei werden Zellobjekte in der C-API-Dokumentation beschrieben:
"Zellen" -Objekte werden verwendet, um Variablen zu implementieren, auf die von mehreren Bereichen verwiesen wird
Und wir können die Verwendung unseres Verschlusses demonstrieren, indem wir feststellen, dass 'foo'
er in der Funktion steckt und sich nicht ändert:
>>> closure_instance('bar')
foo bar
>>> closure_instance('baz')
foo baz
>>> closure_instance('quux')
foo quux
Und nichts kann es ändern:
>>> closure_instance.__closure__ = None
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: readonly attribute
Teilfunktionen
In dem angegebenen Beispiel wird der Verschluss als Teilfunktion verwendet. Wenn dies jedoch unser einziges Ziel ist, kann dasselbe Ziel erreicht werden functools.partial
>>> from __future__ import print_function # use this if you're in Python 2.
>>> partial_function = functools.partial(print, 'foo')
>>> partial_function('bar')
foo bar
>>> partial_function('baz')
foo baz
>>> partial_function('quux')
foo quux
Es gibt auch kompliziertere Verschlüsse, die nicht zum Teilfunktionsbeispiel passen, und ich werde sie weiter demonstrieren, wenn es die Zeit erlaubt.
nonlocal
Python 2.x in Python 3 hinzugefügt wurde und keine vollständigen Lese- / Schreibabschlüsse hatte (dh Sie konnten geschlossene Variablen lesen, aber ihre Werte nicht ändern)