为什么这会发生在课堂上

时间:2013-10-31 13:46:31

标签: python class python-2.7

我写过以下课程,其中包括以下内容:

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保持值。 可能是什么原因

3 个答案:

答案 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)

类没有任何(或没有多少)与此有关。潜在的影响是几个变量可以保持相同的列表(这通过赋值发生)。如果您随后更改列表,则所有变量似乎都会发生变化。

您可能希望创建列表的副本以避免这种情况。