1

我写了以下类,它执行以下操作:

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

4

3 回答 3

7

为什么你会有其他想法?起初,您将 指定lastval为指向与 相同的列表self.Values,因此对一个的突变将在另一个中看到。但是当你这样做时,lastval = []你只是重新绑定lastval到一个新列表,你根本不会影响self.Values

于 2013-10-31T13:49:22.607 回答
4

After the __init__ method has run, we have two objects in memory:

#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:

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. 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. 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. 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.

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.)

于 2013-10-31T14:02:09.153 回答
0

课程与此无关(或没有太大关系)。潜在的影响是多个变量可以保存相同的列表(这通过赋值发生)。如果您随后更改列表,所有变量似乎都发生了变化。

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

于 2013-10-31T13:52:54.533 回答