изменяемые атрибуты python3 являются общими? - PullRequest
0 голосов
/ 07 декабря 2018

В коде я создаю два разных объекта одного и того же класса, как это возможно, что object1 изменяет атрибуты object2?Как я могу сохранить различные переменные "self.mutable"?Где моя ошибка?: -)

спасибо

class Class:
    mutable = {}
    immutable = 0

    def change(self):
        self.immutable = 1
        self.mutable["key"] = "value"

    def observe(self):
        print(self.immutable, self.mutable)


object1, object2 = Class(), Class()

object1.change()
object2.observe()
# output is: 0 {'key': 'value'}

1 Ответ

0 голосов
/ 07 декабря 2018

Вы определили mutable и immutable на уровне класса, поэтому оба будут общими во всех экземплярах Class.Ответы в связанном вопросе подробно объясняют, как избежать поведения совместного использования, которое вы наблюдаете, поэтому я просто объясню, что происходит с вашим кодом.

В принципе, это совместное использование не связано с изменяемыми илинеизменяемый, но в вашем коде есть некоторые нюансы, которые могут запутать его.

В случае mutable наблюдаемое поведение довольно легко объяснить.

Прежде всего,dict mutable - это всегда один и тот же объект в памяти:

>>> o1, o2 = Class(), Class()                                                                         
>>> o1.mutable is o2.mutable is Class.mutable                                                         
True

, когда вы изменяете каким-либо образом mutate, это изменение будет видно везде, где содержится ссылка на этот dict.

>>> Class.mutable                                                                                     
{}
>>> o2.mutable[1] = 2                                                                                 
>>> o1.change()                                                                                       
>>> Class.mutable                                                                                     
{1: 2, 'key': 'value'}

Пока все это ожидается.Сложность с immutable в том, что вы не изменяете Class.mutable при изменении, вы присваиваете атрибут mutable экземпляру (self) change вызывается!

Перед вызовом изменения immutable существует только на уровне класса и доступен через класс при поиске на экземпляре o1 или o2.(Обратите внимание, что значения в экземплярах o1 и o2 пусты.)

>>> o1, o2 = Class(), Class()                                                                         
>>> o1.immutable, o2.immutable, Class.immutable                                                       
(0, 0, 0)
>>> o1.__dict__, o2.__dict__, 'immutable' in Class.__dict__                                           
({}, {}, True)

При вызове change для o2 атрибут immutable = 1 устанавливается только для экземпляра o2!

>>> o2.change()                                                                                       
>>> o1.immutable, o2.immutable, Class.immutable                                                       
(0, 1, 0)
>>> o1.__dict__, o2.__dict__, 'immutable' in Class.__dict__                                           
({}, {'immutable': 1}, True)
>>> o1.immutable is Class.immutable                                                                   
True
>>> o2.immutable is Class.immutable                                                                   
False

Важно понимать, что изменяемые и неизменяемые объекты, установленные на уровне класса, используются одинаково.Разница лишь в том, что у изменяемых объектов нет методов, которые их изменяют.Но если вы сделали self.mutable = {'key': 'value'} в change и затем вызвали change в конкретном экземпляре, атрибут mutable, определенный в экземпляре, будет иметь приоритет над атрибутом, определенным на уровне класса, при поиске в экземпляречерез точечные обозначения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...