在Python中创建对象列表

时间:2008-12-07 22:15:46

标签: python list object loops

我正在尝试创建一个打开多个数据库并比较其内容的Python脚本。在创建该脚本的过程中,我遇到了创建列表的问题,该列表的内容是我创建的对象。

我已经简化了这个帖子的简单程序。首先,我创建一个新类,创建一个新实例,为其分配一个属性,然后将其写入列表。然后我为实例分配一个新值,然后再次将其写入列表......并一次又一次......

问题是,它始终是同一个对象所以我只是在改变基础对象。当我读到列表时,我反复重复同一个对象。

那么如何在循环中将对象写入列表呢?

这是我的简化代码

class SimpleClass(object):
    pass

x = SimpleClass
# Then create an empty list
simpleList = []
#Then loop through from 0 to 3 adding an attribute to the instance 'x' of SimpleClass
for count in range(0,4):       
    # each iteration creates a slightly different attribute value, and then prints it to
# prove that step is working
# but the problem is, I'm always updating a reference to 'x' and what I want to add to
# simplelist is a new instance of x that contains the updated attribute

x.attr1= '*Bob* '* count
print "Loop Count: %s Attribute Value %s" % (count, x.attr1)
simpleList.append(x)

print '-'*20
# And here I print out each instance of the object stored in the list 'simpleList'
# and the problem surfaces.  Every element of 'simpleList' contains the same      attribute value

y = SimpleClass
print "Reading the attributes from the objects in the list"
for count in range(0,4):
    y = simpleList[count]
    print y.attr1

那么我如何(追加,扩展,复制或其他)使用simpleList的元素,以便每个条目包含一个不同的对象实例而不是所有指向同一个实例?

6 个答案:

答案 0 :(得分:59)

你表现出一种根本的误解。

你根本没有创建过SimpleClass的实例,因为你没有调用它。

for count in xrange(4):
    x = SimpleClass()
    x.attr = count
    simplelist.append(x)

或者,如果你让课程参数,你可以使用列表理解。

simplelist = [SimpleClass(count) for count in xrange(4)]

答案 1 :(得分:51)

要使用单独的实例填充列表,可以在列表的声明中使用for循环。 * multiply会将每个副本链接到同一个实例。

instancelist = [ MyClass() for i in range(29)]

然后通过列表索引访问实例。

instancelist[5].attr1 = 'whamma'

答案 2 :(得分:10)

如果你只是简单地使用它来根据其属性输出数据,那么每次都没有必要重新创建SimpleClass对象。但是,您实际上并没有创建该类的实例;您只是创建对类对象本身的引用。因此,您一遍又一遍地向列表(而不是实例属性)添加对同一类属性的引用。

而不是:

x = SimpleClass

你需要:

x = SimpleClass()

答案 3 :(得分:5)

每次创建一个新实例,其中每个新实例都具有正确的状态,而不是不断修改同一实例的状态。

或者,在每一步,而不是原始步骤中存储明确制作的对象副本(使用提示at this page)。

答案 4 :(得分:3)

如果我理解你的问题,你会想办法执行一个对象的深层复制。 使用copy.deepcopy怎么样?

import copy

x = SimpleClass()

for count in range(0,4):
  y = copy.deepcopy(x)
  (...)
  y.attr1= '*Bob* '* count

deepcopy是整个对象的递归副本。有关更多参考,您可以查看python文档:https://docs.python.org/2/library/copy.html

答案 5 :(得分:2)

我认为这只是展示了你想要实现的目标:

# coding: utf-8

class Class():
    count = 0
    names = []

    def __init__(self,name):
        self.number = Class.count
        self.name = name
        Class.count += 1
        Class.names.append(name)

l=[]
l.append(Class("uno"))
l.append(Class("duo"))
print l
print l[0].number, l[0].name
print l[1].number, l[1].name
print Class.count, Class.names

运行上面的代码,你得到: -

[<__main__.Class instance at 0x6311b2c>, 
<__main__.Class instance at 0x63117ec>]
0 uno
1 duo
2 ['uno', 'duo']