简体   繁体   English

为什么在课堂上会发生这种情况

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM