Я должен сказать, что у меня действительно нет проблемы, так как «все работает нормально», но я изо всех сил пытаюсь понять, почему.Непонятное поведение переменных класса
Я пишу скрипт в python/urwid. В моем сценарии у меня есть класс ItemWidget, чья self._w равна urwid.Pile из 3 виджетов, каждая из которых является строкой urwid.Text. Кроме того, класс ItemWidget имеет свойство self.visibility, которое представляет собой список из трех булевых элементов и метод self.rebuild(). Функция инициализации является
def __init__ (self, content,vis):
self.content = content
self.visibility = vis
self.rebuild()
self.__super.__init__(self._w)
Способ восстановления() перестраивает self._w в зависимости от значений в self.visibility().
В основной функции() сценария у меня есть переменная
globalvisibility = [1,1,1]
и создать список (примерно 1000) экземпляров ItemWidget:
for content in abstracts: # (*)
items.append(ItemWidget(content,globalvisibility)) #
На самом деле я использовал переменная, а не
for content in abstracts.items():
items.append(ItemWidget(content,[1,1,1]))
только потому, что позже я реализую сохранение globalvisibility в файл. Но я не думал, что это будет полезно для чего угодно, кроме этой инициализации.
Во всяком случае, в сценарии я часто беру экземпляр ItemWidget и изменить его видимость с помощью, например
item.visibility[2] = 0 # (**)
и подобные. До этого момента все работает нормально и, как ожидалось.
Вот мой вопрос. Почему после создания экземпляров ItemWidget через (*) изменение переменной globalvisibility, скажем, [0,1,1] влияет на все эти экземпляры?
Я должен сказать, что я «обнаружил» это случайно, и это кажется очень полезным (я думал, что для изменения видимости всех экземпляров ItemWidget мне придется перебирать все их), но - для меня - чрезвычайно удивительно. Особенно учитывая, что операции (**) затрагивают только отдельные экземпляры.
Я очень благодарен за объяснения.
EDIT: Весь сценарий здесь: https://www.dropbox.com/s/a0a4a0asyi5lyxw/tescik.py?dl=0 и пример базы данных, из которой я создать экземпляры, если itemwidget является: https://www.dropbox.com/s/zuwbvggznst85ru/arxiv-2013-05-23.db?dl=0
Для того, чтобы запустить его вам нужно изменить строку 58, чтобы указать базы данных. Чтобы увидеть поведение, выделите некоторые элементы и нажмите enter - тезисы исчезнут только на этих элементах, затем нажмите «показать тезисы» - это приведет к сбросу поведения для всех элементов.
Поскольку все ваши экземпляры используют один и тот же объект списка. –
Только для того, чтобы понять, где проблема: выводит ли файл 'a = [1,2,3]; b = a; a.append (4); print (b); 'также удивите вас? – DSM
@ DSM: позвольте мне сказать так: меня удивляет, что я могу изменить свойство vis через (**) в конкретных случаях (разные экземпляры имеют разные значения), но тогда, когда я устанавливаю глобальную видимость на что-то, тогда все они перезагружаются то же самое –