我写过以下课程,其中包括以下内容:
class abc:
def __init__(self):
self.Values = []
def add_code(self):
lastval = self.Values
print "self.Values , ", self.Values
print "lastval , ", lastval
lastval.append(1)
print "self.Values 1, ", self.Values
print "lastval 1 , ", lastval
lastval.append(2)
print "lastval 2 , ", lastval
print "self.Values 2 , ", self.Values
lastval.append(3)
print "lastval 3 , ", lastval
print "self.Values 3 , ", self.Values
lastval.append(4)
print "last val 4 ", lastval
print "self.Values 4 , ", self.Values
lastval = []
print "last value is emtpy now? , ", lastval
print "But the self.Values is not", self.Values
return lastval
当我运行此代码时,我发现变量lastval
附加了值,self.Values
也是如此
但是当我使用空列表初始化lastval
时,我仍然看到self.Values
保持值。
可能是什么原因
答案 0 :(得分:7)
为什么你会这么想?首先,您指定lastval
指向与self.Values
相同的列表,因此在另一个中可以看到一个突变。但是当您执行lastval = []
时,只需将lastval
重新绑定到新列表,就不会影响self.Values
。
答案 1 :(得分:4)
运行__init__
方法后,内存中有两个对象:
#1 Instance of abc
#2 Array
它们包含:
#1 Instance of abc
Values : Reference to #2
#2 Array
[ ]
现在我们调用add_code并运行:
lastval = self.Values
print "self.Values , ", self.Values
print "lastval , ", lastval
此时,lastval和self.Values都是引用到对象#2,即数组。所以我们有:
#1 Instance of abc
Values : Reference to #2
#2 Array
[ ]
Local variables
self : Reference to #1
lastval : Reference to #2
...继续
lastval.append(1)
print "self.Values 1, ", self.Values
print "lastval 1 , ", lastval
append
方法修改对象#2。所以现在我们有:
#1 Instance of abc
Values : Reference to #2
#2 Array
[ 1 ]
Local variables
self : Reference to #1
lastval : Reference to #2
这种情况同样如此......
lastval.append(2)
print "lastval 2 , ", lastval
print "self.Values 2 , ", self.Values
lastval.append(3)
print "lastval 3 , ", lastval
print "self.Values 3 , ", self.Values
lastval.append(4)
print "last val 4 ", lastval
print "self.Values 4 , ", self.Values
现在我们有:
#1 Instance of abc
Values : Reference to #2
#2 Array
[ 1, 2, 3, 4 ]
Local variables
self : Reference to #1
lastval : Reference to #2
此时,我们做了不同的事情:
lastval = []
这是对局部变量的赋值。它对#2没有任何作用。它创建了一个新数组。最后我们有:
#1 Instance of abc
Values : Reference to #2
#2 Array
[ 1, 2, 3, 4 ]
#3 Array
[ ]
Local variables
self : Reference to #1
lastval : Reference to #3
如您所见,lastval和self.Values现在引用不同的对象。
要理解的重要一点是更新变量以引用不同对象和改变现有对象的区别。有关深入讨论,请参阅http://docs.python.org/3/reference/datamodel.html(该文档适用于Python 3,但Python 2和Python 3之间的这些概念没有重大区别。)
答案 2 :(得分:0)
类没有任何(或没有多少)与此有关。潜在的影响是几个变量可以保持相同的列表(这通过赋值发生)。如果您随后更改列表,则所有变量似乎都会发生变化。
您可能希望创建列表的副本以避免这种情况。