экземпляр.__dict__

#python #attributes

#python #атрибуты

Вопрос:

Код идет первым:

 class A(object):
    def foo(self):
        self.foo = 'foo'
    def bar(self):
        self.bar = 'bar'

cls_dict = dict(A.__dict__)  #not empty

a = A()
a_dict = dict(a.__dict__)  #empty, why?
  

Комментарии:

1. cafepy.com/article/python_attributes_and_methods /… объясняет это довольно хорошо: __dict__ содержит только атрибуты непосредственно «на» объекте.

2. во-первых, что вы ожидали там увидеть?

3. @li.davidm, directly on the object ? Те attr, которые определены в классе, не учитываются?

4. @Alcott: Нет, поскольку они являются «отдельными» (в некотором смысле). И классы, и экземпляры являются объектами, и экземпляр может заменять атрибуты, определенные для объекта, поэтому они разделены. Страница, на которую я ссылался, намного более понятна.

Ответ №1:

В Python все является объектом, содержащим атрибуты. Это включает в себя сами классы. Вся объектно-ориентированная вещь с классами, которые определяют методы и экземпляры, которые могут выполнять эти методы с различными данными для каждого экземпляра, — это просто протокол для поиска атрибутов в серии объектов.

 class A(object):
    def foo(self):
        self.foo = 'foo'
    def bar(self):
        self.bar = 'bar'
  

Это создает объект класса, привязанный к имени A . Этот объект содержит два атрибута foo и bar , каждый из которых связан с объектами метода.

 a = A()
  

Это создает объект, привязанный к имени a , который является экземпляром A . Пока он вообще не содержит атрибутов. Но тот факт, что это экземпляр A , означает, что «протокол поиска», когда вы запрашиваете a.foo , заключается в том, чтобы сначала искать атрибут on a , а затем, если это не удается, искать атрибут on A . Так все экземпляры A могут получить доступ к одному и тому же набору методов.

Кроме того, в Python вы можете создавать атрибуты для (почти) любого объекта в любое время. Все, что для этого требуется, это some_object.some_attribute = some_value . Пока вы этого не сделаете, атрибут не существует. Таким образом, при фактическом вызове a.foo() or a.bar() эти foo bar атрибуты и не существуют a (как и любые другие атрибуты, которые ваша программа может или не может однажды добавить к этому объекту), поэтому a.__dict__ в точке, где вы его вызвали, пусто. Если вы ожидаете, что значения по умолчанию foo и bar будут существовать для каждого объекта, вам нужно сказать об этом, установив эти значения в __init__ методе.

Ответ №2:

a.__dict__ пусто, потому что ни один из атрибутов не был инициализирован в экземпляре, поскольку он не __init__() определен. Между тем, класс является объектом, и он инициализировал некоторые атрибуты.

 >>> A
<class '__main__.A'>