Python. Поведение атрибутов странного класса

>>> class Abcd: ... a = '' ... menu = ['a', 'b', 'c'] ... >>> a = Abcd() >>> b = Abcd() >>> aa = 'a' >>> ba = 'b' >>> aa 'a' >>> ba 'b' 

Это все правильно, и у каждого объекта есть свой 'a', но …

 >>> a.menu.pop() 'c' >>> a.menu ['a', 'b'] >>> b.menu ['a', 'b'] 

Как такое могло произойти? И как использовать список как атрибут класса?

3 Solutions collect form web for “Python. Поведение атрибутов странного класса”

Это связано с тем, что вы инициализируете свойство menu устанавливая все экземпляры, указывающие на один и тот же список, в отличие от разных списков с одинаковым значением.

Вместо этого используйте функцию __init__ члена класса для инициализации значений, создав таким образом новый список и присвойв этому списку свойство для этого конкретного экземпляра класса:

 class Abcd: def __init__(self): self.a = '' self.menu = ['a', 'b', 'c'] 

См. Класс-объекты в учебнике и обратите внимание на использование self .

Используйте атрибуты экземпляра, а не атрибуты класса (а также новые классы стилей):

 >>> class Abcd(object): ... def __init__(self): ... self.a = '' ... self.menu = ['a','b','c'] ... >>> a=Abcd() >>> b=Abcd() >>> aa='a' >>> ba='b' >>> aa 'a' >>> ba 'b' >>> a.menu.pop() 'c' >>> a.menu ['a', 'b'] >>> b.menu ['a', 'b', 'c'] >>> 

потому что переменные в Python – это просто «метки»,

оба Abcd.menu и a.menu ссылаются на один и тот же объект списка.

в вашем случае вы должны назначить метку новому объекту,

не изменять объект в месте.

Вы можете запустить

 a.menu = a.menu[:-1] 

вместо

 a.menu.pop() 

почувствовать разницу

  • Как создать свойство класса только для чтения в Python?
  • класс не определен, несмотря на импорт
  • Почему процедуры поиска для получения атрибута из класса и из другого экземпляра?
  • Использование самоопределенного кода Cython из другого кода Cython
  • Не удается наследовать от нескольких классов, определяющих __slots__?
  • Где документация Python для специальных методов? (__init__, __new__, __len__, ...)
  • Идиоматически преобразовывать объект BaseClass в объект SubClass?
  • Перегрузка операторов сложения, вычитания и умножения
  • Доступ к переменным-членам класса в Python?
  • Python - лучший язык программирования в мире.