【问题标题】:Adding instance to a list creates similar values将实例添加到列表会创建类似的值
【发布时间】:2018-04-03 09:41:09
【问题描述】:

我有一个需要附加到列表的类的实例。但是,在追加 N 个实例时,列表的值是最后插入的实例。

这是我正在尝试做的复制(原始文件很大):

class SomeParent:
  listOfObject = []
  tempObject = None

  def addObjects(self):
    for i in range(10):
      self.tempObject = Child()
      self.changeTempObjectX(i)
      listOfObject.append(self.tempObject)

  def changeTempObjectX(self, i):
      self.tempObject.x = i

class Child:
  x = None

问题:理论上,listOfObject 应该包含 10 个具有不同 x 属性 (0-9) 的 Child 类实例。发生的情况是listOfObject(所有这些)的值与最后插入的实例相同。

我在搜索时发现这与可变性和引用有关。我认为正在发生的事情是,插入到列表中的是对先前值的引用,而先前值又会指向最后插入的值。

尝试过:listOfObject转换为元组,加法操作是这样的self.listOfObject = self.listOfObject + (self.tempObject,)。我还尝试使用所有类型的copy,但都不起作用。

我知道应用程序的结构,我不需要更改它,因为重构代码需要大量的努力。创建、编辑和保存实例非常简单。

如何将类的实例插入到列表中?

【问题讨论】:

  • 我已经尝试过了,但它不起作用。 (在帖子中提到)
  • 将类的实例插入到列表中。问题是,由于我是从引用中插入的,因此这些值也会随着时间而变化。我不能简单地做 list.append(Class())
  • 您的示例按预期工作......虽然它在listOfObject 之前缺少self.
  • 您能解释一下您是如何尝试访问列表值的,因为我可以使用您的代码获取所有 10 个值。
  • @Fabbus 同意了。需要self.listOfObject.append(self.tempObject)

标签: python python-3.x oop


【解决方案1】:

问题是x 是Child 的一个属性。它不是实例的属性。因此,可以通过将x 替换为__init__ 来简单地解决此问题

class Child:
  def __init__(self):
    self.x = None

【讨论】:

    【解决方案2】:
    class SomeParent:
      def __init__(self):
        self.listOfObject = []
        self.tempObject = None
    
      def addObjects(self):
        for i in range(10):
          self.tempObject = Child()
          self.changeTempObjectX(i)
          self.listOfObject.append(self.tempObject)
    
      def changeTempObjectX(self, i):
          self.tempObject.x = i
    
      def output(self):
          for i in range(10):
              print self.listOfObject[i].x
    
    class Child:
      x = None
    
    sp = SomeParent()
    sp.addObjects()
    sp.output()
    

    我修复了你的代码。你的代码不工作。下次更好地测试您的最小示例。所以我不能指出你的问题出在哪里,因为你的例子不起作用。但是检查我的固定版本,输出是正确的。你会得到不同的对象。

    【讨论】:

      【解决方案3】:

      尝试执行这个 -

      class SomeParent:
        listOfObject = []
        tempObject = None
      
        def addObjects(self):
          for i in range(10):
            self.tempObject = Child()
            self.changeTempObjectX(i)
            self.listOfObject.append(self.tempObject)
      
        def changeTempObjectX(self, i):
            self.tempObject.x = i
      
      class Child:
        x = None
      
      testObject = SomeParent()
      testObject.addObjects()
      for each in testObject.listOfObject:
          print each.x
      

      【讨论】:

        【解决方案4】:

        您错过了在listOfObject 之前添加自我。使用初始化属性的__init__ 函数是一种很好的做法。你可以试试下面的程序。

        class SomeParent(object):
          def __init__(self):
            self.listOfObject = []
            self.tempObject = None    
          def addObjects(self):
            for i in range(10):
              self.tempObject = Child()
              self.changeTempObjectX(i)
              self.listOfObject.append(self.tempObject)   # ==> Line where you missed self
        
          def changeTempObjectX(self, i):
              self.tempObject.x = i
        
        class Child(object):
          def __init__(self):
            self.x = None
        
        sp = SomeParent()
        sp.addObjects()
        print(sp.listOfObject)
        
        listOfObject = sp.listOfObject[:]
        
        for child_object in listOfObject:
          print(child_object.x)
        

        输出:

        [<Child object at 0x7fdc0e13e438>, <Child object at 0x7fdc0e159be0>, 
         <Child object at 0x7fdc0e159c18>, <Child object at 0x7fdc0e159c50>, 
         <Child object at 0x7fdc0e159c88>, <Child object at 0x7fdc0e159cc0>, 
         <Child object at 0x7fdc0e159cf8>, <Child object at 0x7fdc0e159d30>, 
         <Child object at 0x7fdc0e159d68>, <Child object at 0x7fdc0e159da0>]
        0
        1
        2
        3
        4
        5
        6
        7
        8
        9
        

        如果您在 listOfObject 之前包含了 self ,那么您的程序是正确的,不应该给您相同的值,并且应该五个您的值从 0 到 9。我运行了您的程序

        class SomeParent:
          listOfObject = []
          tempObject = None
        
          def addObjects(self):
            for i in range(10):
              self.tempObject = Child()
              self.changeTempObjectX(i)
              self.listOfObject.append(self.tempObject)  # ==> Line where you 
        
          def changeTempObjectX(self, i):
              self.tempObject.x = i
        
        class Child:
          x = None
        
        sp = SomeParent()
        sp.addObjects()
        print(sp.listOfObject)
        
        
        for child_object in sp.listOfObject:
          print(child_object.x)
        

        输出:

        [<Child object at 0x7f713ad220f0>, <Child object at 0x7f713ad227f0>, 
         <Child object at 0x7f713ad22320>, <Child object at 0x7f713ad22470>, 
         <Child object at 0x7f713a9d6198>, <Child object at 0x7f713a9d6e48>, 
         <Child object at 0x7f713a9d6e80>, <Child object at 0x7f713a9c7c88>, 
         <Child object at 0x7f713a9c7cc0>, <Child object at 0x7f713a9d74e0>]
        0
        1
        2
        3
        4
        5
        6
        7
        8
        9
        

        【讨论】:

          猜你喜欢
          • 2022-01-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-05-19
          • 1970-01-01
          • 2020-03-12
          相关资源
          最近更新 更多