Создание списка объектов в Python

Я пытаюсь создать Python script, который открывает несколько баз данных и сравнивает их содержимое. В процессе создания этого script у меня возникла проблема с созданием списка, содержимое которого - это объекты, которые я создал.

Я упростил программу для своих голых костей для этой публикации. Сначала я создаю новый класс, создаю его новый экземпляр, присваиваю ему атрибут и затем записываю его в список. Затем я назначаю новое значение экземпляру и снова записываю его в список... и снова и снова...

Проблема в том, что это всегда один и тот же объект, поэтому я просто изменяю базовый объект. Когда я читаю список, я снова и снова повторяю один и тот же объект.

Итак, как вы пишете объекты в список в цикле?

Здесь мой упрощенный код

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, чтобы каждая запись содержала другой экземпляр объекта, а не все, указывающие на один и тот же?

Ответ 1

Вы демонстрируете фундаментальное недоразумение.

Вы никогда не создавали экземпляр SimpleClass вообще, потому что вы его не называли.

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

Или, если вы позволите классу брать параметры, вместо этого вы можете использовать понимание списка.

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

Ответ 2

Чтобы заполнить список отдельными экземплярами класса, вы можете использовать цикл for в объявлении списка. * Multiply свяжет каждую копию с одним экземпляром.

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

а затем получить доступ к экземплярам через индекс списка.

instancelist[5].attr1 = 'whamma'

Ответ 3

Не обязательно каждый раз воссоздавать объект SimpleClass, как утверждают некоторые, если вы просто используете его для вывода данных на основе его атрибутов. Однако вы фактически не создаете экземпляр класса; вы просто создаете ссылку на объект класса. Поэтому вы добавляете ссылку на один и тот же атрибут класса в список (вместо атрибута экземпляра) снова и снова.

Вместо:

x = SimpleClass

вам нужно:

x = SimpleClass()

Ответ 4

Создайте новый экземпляр каждый раз, когда каждый новый экземпляр имеет правильное состояние, а не постоянно меняет состояние одного и того же экземпляра.

В качестве альтернативы сохраните явно созданную копию объекта (используя hint на этой странице) на каждом шаге, а не на оригинале.

Ответ 5

Если я правильно понимаю ваш вопрос, вы просите способ выполнить глубокую копию объекта. Как насчет использования copy.deepcopy?

import copy

x = SimpleClass()

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

Глубокая копия - это рекурсивная копия всего объекта. Для получения дополнительной информации вы можете посмотреть документацию python: https://docs.python.org/2/library/copy.html