Das
x in
foo() und das
x in
undo_foo() sind nicht dasselbe
x. Python kennt keinen
Lexical Scope. Vergleiche:
Code: Alles auswählen
# modul xyz
x = 1
def bar():
x = 2
print(x)
bar()
print(x)
Ergebnis:
Das funktioniert, weil die Variable
x in
bar() bei der Zuweisung "entsteht". Dein
x -= 5 bedeutet aber: "Nimm die
bereits lokal bestehende Variable
x, subtrahiere 5 und weise den Wert anschließend wieder
x zu. Das geht natürlich nicht, weil im lokalen Scope kein
x existiert. Du lönntest natürlich eine
nonlocal Anweisung verwenden, was aber ggf. den Programmfluss ziemlich unübersichtlich macht. Der übliche Weg, wie man in Python langlebige Werte verwendet, ist mit Klassen und Objekten:
Code: Alles auswählen
class Baz:
def __init__(self):
self.x = 123
self._undo_list = []
def undo(self):
if self._undo_list:
self._undo_list.pop()
def foo(self):
self.x += 5
@self._undo_list.append
def undo_foo():
self.x -= 5
b = Baz()
print(b.x) # -> 123
b.foo()
print(b.x) # -> 128
b.undo()
print(b.x) # -> 123
Ungetestet.
In specifications, Murphy's Law supersedes Ohm's.