Подтвердить что ты не робот

Доступ к переменным класса через экземпляр

В Python переменные класса могут быть доступны через этот экземпляр класса:

>>> class A(object):
...     x = 4
...
>>> a = A()
>>> a.x
4

Легко показать, что a.x действительно разрешено a.x, а не копируется в экземпляр во время построения:

>>> A.x = 5
>>> a.x
5

Несмотря на то, что это поведение хорошо известно и широко используется, я не смог найти окончательную документацию, охватывающую его. Наиболее близким, которое я мог найти в документах Python, был раздел в классах:

class MyClass:
    """A simple example class"""
    i = 12345
    def f(self):
        return 'hello world'

[надрез]

... По определению все атрибуты класса, которые являются объектами-объектами, определяют соответствующие методы его экземпляров. Поэтому в нашем примере x.f является допустимым методом, так как MyClass.f является функцией, но x.i не является, так как MyClass.i не является....

Однако в этой части речь идет конкретно о методах, поэтому она, вероятно, не относится к общему случаю.

Мой вопрос в том, что это документировано? Могу ли я полагаться на это поведение?

4b9b3361

Ответ 1

Обозначает части Classes и Class instances в http://docs.python.org/reference/datamodel.html

Класс имеет пространство имен, реализуемое объектом словаря. Класс ссылки на атрибуты переводится в поисковые запросы в этом словаре, например, C.x переводится в C.__ dict __ [ "x" ] (хотя для классов нового стиля, в частности, имеется несколько крючков, которые допускают другие способы определения атрибутов)

Экземпляр класса создается путем вызова объекта класса (см. выше). экземпляр класса имеет пространство имен, реализованное как словарь, который первое место, в котором выполняется поиск ссылок атрибутов. Когда атрибут там не найден, а класс экземпляров имеет атрибут по этому имени, поиск продолжается с классом атрибуты.

Как правило, это использование прекрасное, за исключением особых случаев, упомянутых как "классы нового стиля, в частности, есть несколько крючков, которые позволяют использовать другие способы определения атрибутов".

Ответ 2

Вы можете не только полагаться на это поведение, но и постоянно.

Подумайте о методах. Метод - это просто функция, которая была сделана атрибутом класса. Затем вы посмотрите на экземпляр.

>>> def foo(self, x):
...     print "foo:", self, x
... 
>>> class C(object):
...     method = foo # What a weird way to write this! But perhaps illustrative?
... 
>>> C().method("hello")
foo: <__main__.C object at 0xadad50> hello

В случае объектов, подобных функциям, это не простой поиск, но возникает какая-то магия, чтобы передать self автоматически. Возможно, вы использовали другие объекты, предназначенные для хранения в качестве атрибутов класса, и просмотрели экземпляр; свойства являются примером (ознакомьтесь с property встроенным, если вы не знакомы с ним.)

Как примечания okm, способ, которым это работает, описан в ссылке на модель данных (включая информацию о ссылках на дополнительную информацию о магии, которая делает методы и свойства работы). Страница модели данных является, безусловно, наиболее полезной частью справочника языка; он также включает, помимо прочего, документацию почти о всех методах и именах __foo__.