Как мне получить dict атрибутов класса Python (не экземпляра)?

#python #dictionary

#python #словарь

Вопрос:

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

Я видел ответы на этом сайте, которые предполагают, что класс __dict__ предоставит это, как я пытался с этим кодом:

 class Item:
    def __init__(self):
        self.name = ''
        self.description = ''
        self.weight = ''
        self.volume = ''

print(Item.__dict__)

{'__module__': '__main__', '__init__': <function Item.__init__ at 0x0000026F3F5988C8>, '__dict__': <attribute '__dict__' of 'Item' objects>, '__weakref__': <attribute '__weakref__' of 'Item' objects>, '__doc__': None}
  

Кажется, я хочу получить доступ Item.__dict__.['__dict__'] , но я не знаю, как это сделать.

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

1. Попробуйте, Item().__dict__ . Item.__dict__ получит только class атрибут, а не instance атрибуты, о чем вы просите 🙂

2. @hansolo, хорошо заметил 🙂 Я думаю, это стоит превратить в ответ.

3. На самом деле, я хочу изменить значение атрибута класса.

4. Item.__dict__ это ответ на вопрос в названии. Что именно вы хотите?

5. @Buffersnuff Но ваш класс Item не имеет никаких атрибутов класса. имя, описание и т. Д. Являются Атрибутами экземпляра. Если вам нужен атрибут класса, вы бы определили их вне __init__ . Например, class Item: <newline> <tab> foo=1 <newline> <tab> def __init__(self): <rest of class goes here> .

Ответ №1:

Как указывали другие, чтобы увидеть атрибуты экземпляра (а не атрибуты класса), вам нужно будет создать экземпляр объекта этого типа. Однако вместо использования __dict__ атрибута предпочтительнее использовать встроенную vars функцию.

 item = Item()
items_attrs = vars(item)
  

Это делает то же самое под капотом, но выглядит немного более питоническим.


Вы также можете определить __slots__ атрибут для класса. Это изменит поведение класса (и его объектов), что, возможно, нежелательно, но позволит вам легко получить доступ к интересующей вас информации. Примечательно, что это поведение меняется:

Без __dict__ переменной экземплярам не могут быть назначены новые переменные, не перечисленные в __slots__ определении. Попытки присвоить имя переменной, не включенной в список, повышаются AttributeError . Если требуется динамическое присвоение новых переменных, добавьте '__dict__' к последовательности строк в __slots__ объявлении.

 class Item(object):
    __slots__ = ['name',
        'description',
        'weight',
        'volume']

    def __init__(self):
        self.name = ''
        self.description = ''
        self.weight = ''
        self.volume = ''

Item_attrs = Item.__slots__
item = Item()
item_attrs = item.__slots__

assert item_attrs == Item_attrs
  

Ответ №2:

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

 class Item:
    classvar = 'foo'

    def __init__(self):
        self.name = ''
        self.description = ''
        self.weight = ''
        self.volume = ''
  

Теперь Item.__dict__ будет содержать classvar . Но переменные экземпляра не создаются до тех пор, пока не будет создан экземпляр класса:

 i1 = Item()
print(i1.__dict__())  # will contain 'name', 'description' etc.
  

Однако, почему вы хотите поиграть с __dict__ ? Это необходимо только для некоторых трюков самоанализа кода. Вы можете получить доступ к переменным класса и экземпляра просто с помощью точечной нотации:

 print(Item.classvar)
i1 = Item()
print(i1.name)
  

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

1. Теперь, когда вы прояснили это для меня, мне не нужно будет возиться __dict__ . Большое спасибо.