Skip to content

Instantly share code, notes, and snippets.

@inesusvet
Created June 28, 2013 08:07
Show Gist options
  • Save inesusvet/5883212 to your computer and use it in GitHub Desktop.
Save inesusvet/5883212 to your computer and use it in GitHub Desktop.
Задача в том чтобы иметь объяснение почему в строке 4 нет ошибки, в то время как в строке 8 значения различаются
In [1]: class Foo(object):
...: attr = {'initial_state': True}
...: def bar_class(self):
...: self.attr['initial_state'] = False
...: def bar_instance(self):
...: self.attr = {'initial_state': False}
...:
In [2]: foo = Foo()
In [3]: foo.bar_class()
In [4]: assert Foo.attr == foo.attr == {'initial_state': False}
In [5]: class Foo(object):
...: attr = {'initial_state': True}
...: def bar_class(self):
...: self.attr['initial_state'] = False
...: def bar_instance(self):
...: self.attr = {'initial_state': False}
...:
In [6]: foo = Foo()
In [7]: foo.bar_instance()
In [8]: Foo.attr, foo.attr
Out[8]: ({'initial_state': True}, {'initial_state': False})
In [9]:
@lssergey
Copy link

В bar_class меняется уже имеющийся mutable-объект, на который ссылаются и Foo.attr и foo.attr. В bar_instance создаётся новый объект, никак не связанный с тем, что был создан при инициализации класса.

@inesusvet
Copy link
Author

Где создается новый объект? Какой объект был создан при инициализации класса?

@lssergey
Copy link

После создания объекта, у foo нет атрибута attr. Поэтому, когда мы вызываем в 3-й строке bar_class, self.attr — это на самом деле self.__class__.attr, который интерпретатор находит в дереве предков у класса Foo, который мы и меняем. В bar_instance у нашего объекта появляется свой атрибут attr, и теперь при вызове self.attr интерпретатор возвращает объект, на который ссылается self.attr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment