#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__
. Большое спасибо.