I'm trying to use the with..as contruct in Python to make writing "reversible computing" code easier. However, using @contextmanager
on a class method seems to change the default initialization of future class instances. Python 2.6 and 3.1 have the same behavior. Here is a simple example exhibiting this behavior:
#!/usr/bin/env python
import contextlib
class SymList:
def __init__(self, L=[]):
self.L = L
@contextlib.contextmanager
def SymAdd(self, a):
self.L.append(a)
yield
self.L.append(a)
SL = SymList()
with SL.SymAdd(3):
SL.L.append(5)
print(SL.L) # Expect and see [3, 5, 3]
SL2 = SymList()
print(SL2.L) # Expect [] and see [3, 5, 3]
SL2
a fresh instance of SymList
?SL2.L
data member referring to the SL.L
data member?This behavior is due to how mutable default arguments work in Python.
Try changing SymList.__init__()
to the following:
def __init__(self, L=None):
if L is None:
self.L = []
else:
self.L = L
As you modify self.L
in one instance you are also modifying the L
that is passed into SymList.__init__()
, so the result with your code is that all instances would share the same L
attribute when the instance is first initialized.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With