可能重复:
“Least Astonishment” in Python: The Mutable Default Argument
我显然在这里遗漏了一些内容:任何人都可以解释为什么t1
“神秘地”获得self.thelist
t2
的价值?我做错了什么?
>>> class ThingyWithAList(object):
... def __init__(self, alist=[]):
... super(ThingyWithAList, self).__init__()
... self.thelist = alist
...
>>> t1 = ThingyWithAList()
>>> t1.thelist.append('foo')
>>> t1.thelist.append('bar')
>>> print t1, t1.thelist
<__main__.ThingyWithAList object at 0x1004a8350> ['foo', 'bar']
>>>
>>> t2 = ThingyWithAList()
>>> print t2, t2.thelist
<__main__.ThingyWithAList object at 0x1004a8210> ['foo', 'bar']
答案 0 :(得分:3)
因为默认参数'alist = []',所以在读取模块时只创建一个列表。这个单一列表成为__init__“的默认参数,并由所有Thingys共享。
尝试使用None作为虚拟符号,意味着“在此处创建一个新的空列表”。 E.g。
def __init__(self, alist=None):
super(ThingyWithAList, self).__init__()
self.thelist = [] if alist is None else alist
答案 1 :(得分:2)
如果我做对了,构造函数中用[]
创建的对象引用保持不变。试试这个:
>>> class ThingyWithAList(object):
... def __init__(self, alist=None):
... super(ThingyWithAList, self).__init__()
... self.thelist = alist or []
...
>>> t1 = ThingyWithAList()
>>> t1.thelist.append('foo')
>>> t1.thelist.append('bar')
>>> print t1, t1.thelist
<__main__.ThingyWithAList object at 0xb75099ac> ['foo', 'bar']
>>>
>>> t2 = ThingyWithAList()
>>> print t2, t2.thelist
<__main__.ThingyWithAList object at 0xb7509a6c> []
答案 2 :(得分:2)
“特殊情况不够特别”,因此有条不紊地检查“无”会以错误的方式揉搓我。如果.thelist
确实是一个列表很重要,那么该类也应该强制执行它。
def __init__(self, alist=()):
super(ThingyWithAList, self).__init__()
self.thelist = list(alist)
请注意,现在没有修改默认arg的危险,因为元组是不可变的。