我正在尝试使用Python中的with..as contruct来简化“可逆计算”代码的编写。但是,在类方法上使用@contextmanager
似乎会更改未来类实例的默认初始化。 Python 2.6和3.1具有相同的行为。以下是展示此行为的简单示例:
#!/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
不是SymList
的新实例?SL2.L
数据成员如何引用SL.L
数据成员?答案 0 :(得分:14)
此行为是由于mutable default arguments在Python中的工作原理。
尝试将SymList.__init__()
更改为以下内容:
def __init__(self, L=None):
if L is None:
self.L = []
else:
self.L = L
当您在一个实例中修改self.L
时,您还要修改传递给L
的{{1}},因此您的代码的结果是所有实例将共享相同的SymList.__init__()
L
首次初始化实例时的属性。