6

我有这个简单的课程:

class revs:
    def __init__(self, rev, us, accs = []):
        self.rev = rev
        self.us = us
        self.accs = accs

我有这段代码可以将值分配给列表并且在循环内

rev, usu = cada_l.split("|")
acct = each_l[:2].strip()
list_acct.append(acct)

最后,我创建了一个字典来管理这样的转速列表:

drevs = {}
cada = revs(rev, us, list_acct)
drevs[cada.rev] = cada

它适用于 rev 和 us,但 list_acct 会更新所有实例:

drevs['1'].rev
'1'
drevs['2'].rev
'2'
drevs['1'].us
'user1'
drevs['2'].us
'user2'
drevs['1'].accs
'["Doc1","Doc2"]'
drevs['2'].accs
'["Doc1","Doc2"]'

如果我更改 list_acct.clear(),所有实例中的值都是明确的,我对 Python 还是很陌生,这让我很困惑。

谢谢

4

1 回答 1

8

这看起来正在发生,因为您将相同的列表传递给每个对象。结果,所有对象都保持对同一列表的引用,并且由于list是可变的,因此它似乎一次更改了“所有”对象。

要解决此问题,请在每次创建对象时传入一个revs的空列表,或者克隆您传入的列表:

cada = revs(rev, us, list_acct[:])

请注意,如果list_acct包含可变对象,您仍然可能再次遇到相同的问题,但更深一层!

如果您在revs创建对象时根本没有将列表传递给对象(我不知道,因为您没有显示完整的代码!),那么您会遇到同样的问题,但原因不同:在 Python , 默认参数都在函数定义时计算一次。因此,您可以获得此行为:

r1 = revs(1, 1)
r2 = revs(2, 2)
r1.accs.append("Hi!")
print(r1.accs) # prints ['Hi!']
print(r2.accs) # prints ['Hi!']

因为revs构造函数的默认参数总是指向同一个列表。请参阅此问题以获取有关原因的解释,但要绕过它,只需将None其用作默认值而不是[].

class revs:
    def __init__(self, rev, us, accs=None):
        self.rev = rev
        self.us = us
        if accs is None:
            accs = []
        self.accs = accs
于 2013-05-23T17:37:17.013 回答