这是我的伪代码:
class foo(bar):
def __init__(self, aList):
bar.__init__(self, aList)
self.initialList = aList
def clock(self):
modify(self.workingList)
if(something):
self.workingList = self.initialList
assert self.initialList == range(10)
class bar(object):
def __init__(self, aList):
self.workingList = aList
程序的正常操作如下:
a = range(10)
b = foo(a)
for i in xrange(10000):
b.clock()
这不起作用因为我做了
self.workingList = self.initialList
self.workingList指向同一个对象而不是复制它。那么当我做的时候
modify(self.workingList)
它还修改了self.initialList,它意味着保持不变。
我的解决方法是替换
self.workingList = self.initialList
与
self.workingList = [i for i in self.initialList]
我甚至更换了
self.initialList = aList
使用:
self.initialList = [j for j in aList]
虽然我认为这应该在原则上有效,但它并没有在实践中解决问题。我通过assert语句验证了这一点。我似乎误解了一些pythonic语义。有人可以解释一下吗?
谢谢!
编辑: 请注意,我理解deepcopy和shallowcopy之间的区别。这不是我的问题所在。当我在类实例化/继承中使用它时,我觉得有些东西搞砸了。我正在离线工作以生成我可以在这里提供的MCV代码。请继续关注该更新。
更新:
我在MCVE中找到了C,这是错误:
class bar(object):
def __init__(self, aList):
self.workingList = aList
class foo(bar):
def __init__(self, aList):
bar.__init__(self, aList)
self.initialList = list(aList)
def clock(self):
self.workingList[2] = max(self.workingList[3], 2)
#print self.workingList
if(1):
self.workingList = list(self.initialList)
try:
assert self.initialList == range(10)
except:
print self.initialList
print self.workingList
assert self.initialList == range(10)
a = range(10)
for i in xrange(10):
b = foo(a)
for j in xrange(100000):
b.clock()
答案 0 :(得分:-1)
经过大量调试后我发现了这个bug的原因。一种可能的解决方法如下:
class bar(object):
def __init__(self, aList):
self.workingList = list(aList) #aList
原因是python按值传递对象引用。这是一个link,可以很好地解释它。
它与我的代码有关的方式是每次我在foo.clock()中更改self.workingList:
modify(self.workingList)
它实际上修改了aList指向的对象(在构造函数之外!!),所以当我创建一个新的foo实例(aList)时,我将一个新的错误版本的aList传递给它。这太棒了!
最棘手的事情是重新分配self.workingList不会创建这个错误(虽然它会传递引用),但修改self.workingList会,因为python按值传递对象引用(所有这些都被解释)详情请见link)