【发布时间】:2012-12-15 17:55:50
【问题描述】:
可能重复:
“Least Astonishment” in Python: The Mutable Default Argument
当我尝试编写如下所示的类时,我遇到了一些很奇怪的事情。在第 3 行,我必须将参数 newdata 的新副本放到 self.data 中,否则,似乎当我启动一个新的类实例时,前一个的值仍然被类记住。请看下面的例子,请注意第 3 行两个版本代码的唯一区别。
class Pt(object):
def __init__(self,newdata={}):
self.data=newdata.copy()
if self.data == {}:
self._taglist = []
else:
self._taglist = self.data.keys()
def add_tag(self,tag=None):
self.data[tag]={'x':[0,1,2,3,4]}
self._taglist.append(tag)
In [49]: pt = Pt()
In [50]: pt.add_tag('b')
In [51]: pt.add_tag('a')
In [52]: pt.data
Out[52]: {'a': {'x': [0, 1, 2, 3, 4]}, 'b': {'x': [0, 1, 2, 3, 4]}}
In [53]: pt2 = Pt()
In [54]: pt2._taglist
Out[54]: []
class Pt(object):
def __init__(self,newdata={}):
self.data=newdata
if self.data == {}:
self._taglist = []
else:
self._taglist = self.data.keys()
def add_tag(self,tag=None):
self.data[tag]={'x':[0,1,2,3,4]}
self._taglist.append(tag)
In [56]: pt = Pt()
In [57]: pt.add_tag('a')
In [58]: pt.add_tag('b')
In [59]: pt._taglist
Out[59]: ['a', 'b']
In [60]: pt2 = Pt()
In [61]: pt2._taglist
Out[61]: ['a', 'b']
In [62]: pt2.data
Out[62]: {'a': {'x': [0, 1, 2, 3, 4]}, 'b': {'x': [0, 1, 2, 3, 4]}}
我猜第二种情况的发生是因为:newdata 和 self.data 都引用同一个对象(但怎么会发生这种情况,值应该从右到左而不是反向给出),所以当我使用“ add_tag" 方法来更新 self.data,newdata 也会更新。然而我认为当我通过pt2 = Pt()启动一个新实例时,newdata应该使用默认值({}),它仍然可以保留pt1的旧值吗?
【问题讨论】:
-
你不应该使用可变对象作为默认值。
标签: python class dictionary instance