Werfen wir einen Blick auf die Implementierung von Schließungen basierend auf dem Inhalt des vorherigen Artikels (Ich habe untersucht, wie der Bereich aussieht).
def counter(x):
pprint(locals())
def count():
pprint(locals())
y = x
x += 1
return y
return count
c = counter(10)
print c()
print c()
print c()
Sieht so aus, als würde es funktionieren, aber wenn ich es tue, erhalte ich den folgenden Fehler:
Ausführungsergebnis
{'x': 10}
{}
Traceback (most recent call last):
File "tes004.py", line 12, in <module>
print c()
File "tes004.py", line 7, in count
y = x
UnboundLocalError: local variable 'x' referenced before assignment
Das Argument x der Funktion counter () erscheint als lokale Variable von counter ().
Wenn Sie sich nur auf die Variable x aus der internen Funktion count () beziehen, kann die Variable x als lokale Variable count () bezeichnet werden, aber der Zuweisungscode ( x + = 1
⇒ Dies ist auch der Referenzcode. ), Es funktioniert also als eine Variable, die im Funktionsblock count () definiert ist, aber ein Fehler tritt auf, weil die Referenz vor der Zuweisung ausgeführt wird.
Sie können auf die durch die äußere Funktion definierten Variablen verweisen, diese jedoch nicht zuweisen (neu schreiben).
Als nächstes folgt ein Muster, das gut ausgeführt werden kann.
def counter(x):
pprint(locals())
y = [x]
def count():
pprint(locals())
z = y[0]
y[0] += 1
return z
return count
c = counter(10)
print c()
print c()
print c()
Ausführungsergebnis
{'x': 10}
{'y': [10]}
10
{'y': [11]}
11
{'y': [12]}
12
Dieser Code scheint auch die Variable y mit der internen Funktion count () neu zu schreiben, funktioniert jedoch einwandfrei, da nur der Inhalt der Liste neu geschrieben wird, auf den die Variable y verweisen kann. Wenn Sie beispielsweise "y [0] + = 1" in "y = [y [0] + 1]" ändern, wird ein Fehler angezeigt. Dies liegt daran, dass wir versuchen, die Variable y neu zu schreiben. Selbst wenn das Referenzziel keine Liste, sondern eine Klasse ist, kann das Referenzziel daher aktualisiert werden.
Das folgende Beispiel ist in einer Klasse implementiert.
class tcls():
def __init__(self, x):
self.x = x
def counter(x):
pprint(locals())
y = tcls(x)
def count():
pprint(locals())
z = y.x
y.x += 1
return z
return count
c = counter(10)
print c()
print c()
print c()
Ausführungsergebnis
{'x': 10}
{'y': <__main__.tcls instance at 0x0222F788>}
10
{'y': <__main__.tcls instance at 0x0222F788>}
11
{'y': <__main__.tcls instance at 0x0222F788>}
12