Создание списка объектов в 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