[英]Why does this happen with classes
I have written following class which does the following: 我写了下面的课,它做以下事情:
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
When I run this code I see that the variable lastval
gets appended with the values and so does the self.Values
But when I initialize the lastval
with empty list, I still see self.Values
holds to the values. 当我运行此代码,我看到变量
lastval
获取与附加价值等做了self.Values
但是,当我初始化lastval
与空列表,我仍然看到self.Values
持有的价值观。 What could be the reason 可能是什么原因
Why would you think otherwise? 你为什么会这样认为呢? At first, you assign
lastval
to point to the same list as self.Values
, so mutations to one will be seen in the other. 首先,您将
lastval
分配为指向与lastval
相同的列表,这样一个self.Values
就会在另一个self.Values
中看到。 But when you do lastval = []
you simply rebind lastval
to a new list, you don't affect self.Values
at all. 但是,当您执行
lastval = []
您只需将lastval
重新绑定到新列表,就根本不会影响self.Values
。
After the __init__
method has run, we have two objects in memory: __init__
方法运行后,内存中有两个对象:
#1 Instance of abc
#2 Array
They contain: 他们包含:
#1 Instance of abc
Values : Reference to #2
#2 Array
[ ]
Now we call add_code and it runs: 现在我们调用add_code并运行:
lastval = self.Values
print "self.Values , ", self.Values
print "lastval , ", lastval
At this point, both lastval and self.Values are references to object #2, the array. 此时,lastval和self.Values都是对对象#2(数组)的引用 。 So we have:
因此,我们有:
#1 Instance of abc
Values : Reference to #2
#2 Array
[ ]
Local variables
self : Reference to #1
lastval : Reference to #2
Continuing... 继续...
lastval.append(1)
print "self.Values 1, ", self.Values
print "lastval 1 , ", lastval
The append
method modifies object #2. append
方法修改对象#2。 So now we have: 现在我们有了:
#1 Instance of abc
Values : Reference to #2
#2 Array
[ 1 ]
Local variables
self : Reference to #1
lastval : Reference to #2
This continues similarly... 这类似地继续...
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
So now we have: 现在我们有了:
#1 Instance of abc
Values : Reference to #2
#2 Array
[ 1, 2, 3, 4 ]
Local variables
self : Reference to #1
lastval : Reference to #2
At this point, we do something different: 在这一点上,我们做一些不同的事情:
lastval = []
This is an assignment to a local variable. 这是对局部变量的赋值。 It doesn't do anything to object #2.
它对对象2没有任何作用。 It creates a new array.
它创建一个新的数组。 So finally we have:
所以最后我们有了:
#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
As you can see, lastval and self.Values now refer to different objects. 如您所见,lastval和self.Value现在引用了不同的对象。
The important thing to understand is the difference updating a variable to reference different objects, and mutating an existing object. 要了解的重要一点是区别在于更新变量以引用不同的对象以及对现有对象进行突变。 For an in-depth discussion, see http://docs.python.org/3/reference/datamodel.html (That document is for Python 3, but there is no major difference in these concepts between Python 2 and Python 3.)
有关深入的讨论,请参见http://docs.python.org/3/reference/datamodel.html (该文档适用于Python 3,但是Python 2和Python 3在这些概念上没有主要区别。)
Classes have nothing (or not much) to do with this. 类与此无关(或不多)。 The underlying effect is that several variables can hold the same list (this happens via assignment).
潜在的影响是几个变量可以保存相同的列表(这通过分配发生)。 And if you then change the list, all variables seem to change.
然后,如果您更改列表,则所有变量似乎都会更改。
You might want to create copies of the lists to avoid that. 您可能想要创建列表的副本来避免这种情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.