为什么这段代码会生成三个数组值而不是一个?python 3.x版

2024-06-19 19:25:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个名为general的类,它的属性是数组msgs[]。还有一个名为msg的属性,它是一个字符串。我实例化了三个类gen0, gen1, gen2,并将每个对象存储在一个名为arr (arr = [gen0, gen1, gen2])的数组中

我在类general上定义了一个名为snd(self, id, somemsg)的方法,该方法给定id(指向数组arr中索引id处的对象),将字符串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']

Tags: id属性定义msgval数组generalarr
1条回答
网友
1楼 · 发布于 2024-06-19 19:25:06

心灵调试:您的general类定义如下:

class general:
    msgs = []

或:

class general:
    def __init__(self, msgs=[]):
        self.msgs = msgs

前者使msgs成为类属性,而不是实例属性,因此它在类及其所有实例之间共享,而后者则与使用默认值的所有实例共享一个list。两种方法的解决方案是相同的:分别使用一个唯一的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等等,所有这些都归结为同一个问题:您要多次存储对同一数据的单个引用,并且需要有不同的值

相关问题 更多 >