我有一个名为general
的类,其数组为msgs[]
作为属性。还有一个名为msg
的属性,它是一个字符串。我实例化了三个类gen0, gen1, gen2
并将每个对象存储在一个名为arr (arr = [gen0, gen1, gen2])
的数组中。
我在类general
上定义了一个名为snd(self, id, somemsg)
的方法,给定了id(指向数组id
中索引arr
处的对象),将字符串somemsg
附加到数组msgs[]
。
例如,gen0.snd(1,"hello")
将执行gen1.msgs.append("hello")
。
def snd(self, dst, msg):
listGens[dst].msgs.append(msg)
我定义了以下函数,其中general
是上面定义的类的实例化。
def playGeneral(general):
for val in listGens:
if(val.id is general.id):
general.snd(general.id, " ")
continue
general.snd(val.id, general.oc)
调用playGeneral(gen0)
时,somemsg
变量已设置为genX.msg = "A"
,即gen0.msg
,恰好是“A”;这样做,我们得到
playGeneral(listGens[0])
for val in listGens:
print(val.msgs)
[' ', 'A', 'A']
[' ', 'A', 'A']
[' ', 'A', 'A']
我无法理解为什么会这样。它应该是屈服的
[' ']
['A']
['A']
答案 0 :(得分:2)
心理调试:您的general
类定义如下:
class general:
msgs = []
或:
class general:
def __init__(self, msgs=[]):
self.msgs = msgs
前者使msgs
成为类属性,而不是实例属性,因此它在类及其所有实例之间共享,而后者与所有使用默认值的实例共享一个list
msgs
。两者的解决方案是相同的:为每个使用唯一的list
:
class general:
def __init__(self, msgs=()):
self.msgs = list(msgs) # Explicitly convert and shallow copy as list
第三种可能性是你做了一些愚蠢的事情,如msgs = []
,gen0 = general(msgs)
,gen1 = general(msgs)
等,或gen0 = gen1 = gen2 = general([])
,或listgens = [general()] * 3
等,所有这些归结为同样的问题:你多次存储对同一数据的单个引用,你需要有不同的值。