Reputation: 31
I want to access attributes in a class so I can change them dynamically.
I have seen answers on this site that suggest the class's __dict__
will provide this, as I tried with this code:
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}
It seems I want to access Item.__dict__.['__dict__']
but I don't know how to do this.
Upvotes: 3
Views: 5024
Reputation: 54273
As others have pointed out, in order to see instance attributes (rather than class attributes), you'll have to instantiate an object of that type. However rather than using the __dict__
attribute, it is preferred to use the builtin vars
function.
item = Item()
items_attrs = vars(item)
This does the same thing under the hood, but appears a bit more Pythonic.
You could also define a __slots__
attribute on the class. This will change the behavior of the class (and its objects) in what is perhaps an unwanted way, but allows you easy access to the information you're interested in. Notably, this behavior changes:
Without a
__dict__
variable, instances cannot be assigned new variables not listed in the__slots__
definition. Attempts to assign to an unlisted variable name raisesAttributeError
. If dynamic assignment of new variables is desired, then add'__dict__'
to the sequence of strings in the__slots__
declaration.
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
Upvotes: 4
Reputation: 2408
You may be confused between class and instance variables. In the following modification of your code, classvar
is a class variable:
class Item:
classvar = 'foo'
def __init__(self):
self.name = ''
self.description = ''
self.weight = ''
self.volume = ''
Now Item.__dict__
will contain classvar
. But instance variables are not created until the class is instantiated:
i1 = Item()
print(i1.__dict__()) # will contain 'name', 'description' etc.
However, why would you want to play around with __dict__
? It is only needed for some code introspection tricks. You can access class and instance variables simply by the dot notation:
print(Item.classvar)
i1 = Item()
print(i1.name)
Upvotes: 0