可能重复:
“Least Astonishment” in Python: The Mutable Default Argument
考虑以下python test.py模块:
class Container:
def __init__(self, str_list=[]):
self.str_list = str_list
def from_strings(self, st=""):
self.str_list.append(st)
return self
o1 = Container().from_strings(st="o1")
o2 = Container().from_strings(st="o2")
o3 = Container().from_strings(st="o3")
def prnt():
print("o1's list:"+str(o1.str_list))
print("o2's list:"+str(o2.str_list))
print("o3's list:"+str(o3.str_list))
if __name__ == '__main__':
prnt()
为什么输出python test.py
:
o1's list:['o1', 'o2', 'o3']
o2's list:['o1', 'o2', 'o3']
o3's list:['o1', 'o2', 'o3']
而不是:
o1's list:['o1']
o2's list:['o2']
o3's list:['o3']
(似乎我不知道为什么同一模块中不同实例的字段(str_list)可能会混淆。指向python doc的指针解释这个概念将受到高度赞赏)
答案 0 :(得分:2)
您在构造函数中创建了一个空列表作为默认值:
def __init__(self, str_list=[]):
self.str_list = str_list
此列表仅创建一次,然后由所有实例共享。如果您想为每个实例创建单独的列表,您可以执行以下操作:
def __init__(self, str_list=None):
self.str_list = [] if str_list is None else str_list
现在每个实例都会创建自己的列表。
修改强>
您可能使用了1
或'foo'
这样的默认参数,但从未出现过问题。
这些不可变对象无法被操纵。无论何时你想到,你都会得到一个新的实例。不可变对象类型的集合包括int
,str
,tuple
等。
现在[]
,list
是可变对象,可以被操纵。因此,每当您更改其上的属性时,它都会更改实际对象,并且对它的每个引用都将反映更改。