【问题标题】:Why does this happen with classes为什么上课会发生这种情况
【发布时间】:2013-10-31 23:57:44
【问题描述】:

我编写了以下课程:

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

【问题讨论】:

    标签: python class python-2.7


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      __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 之间的这些概念没有重大区别。)

      【讨论】:

      • 那是非常详细的解释...我会确保保存您的回复
      【解决方案3】:

      类与此无关(或无关紧要)。潜在的影响是几个变量可以保存相同的列表(这通过赋值发生)。如果您随后更改列表,所有变量似乎都会更改。

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

      【讨论】:

        猜你喜欢
        • 2021-01-24
        • 1970-01-01
        • 2021-04-30
        • 2010-09-22
        • 2018-04-27
        • 2013-08-02
        • 2018-12-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多