为什么不同实例的字段在python模块中混合在一起?
可能重复:为什么不同实例的字段在python模块中混合在一起?,python,python-2.7,Python,Python 2.7,可能重复: 考虑以下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 =
考虑以下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文档的指针)您在构造函数中创建了一个空列表作为默认值:
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
,等等
现在,[]
,一个列表
,是一个可变的对象,可以操作。因此,无论何时更改属性,它都会更改实际对象,对它的每个引用都会反映更改。self.str\u list=str\u list或[]
可能会导致细微错误-如果str\u list为None:str\u list=[]
已更正啊,旧的可变默认参数。这是关于Python您必须学习的内容。@DSM是的,我想也是这样。我猜在我的搜索中没有出现,因为我甚至没有怀疑默认参数,而是认为字段以某种方式混合在一起。