我有这个简单的课程:
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)
最后,我创建了一个dict,来管理这样的转速列表:
drevs = {}
cada = revs(rev, us, list_acct)
drevs[cada.rev] = cada
它与rev和我们一起正常工作,但是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的新手,这让我很困惑。
由于
答案 0 :(得分:7)
这看起来好像正在发生,因为您将相同的列表传递给每个对象。因此,所有对象都维护对同一列表的引用,并且由于list
是可变的,它似乎会立即更改“全部”。
要解决此问题,请在每次创建revs
对象时传入 new 空列表,否则克隆您传入的列表:
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
构造函数的默认参数始终指向同一个列表。有关原因的解释,请参阅this question,但要解决此问题,只需使用None
作为默认值而不是[]
。
class revs:
def __init__(self, rev, us, accs=None):
self.rev = rev
self.us = us
if accs is None:
accs = []
self.accs = accs