Skip to content Skip to sidebar Skip to footer

Convert Dict Attributes In Multiple Attributes In Python

I have a class with a dict attribute, like this : class MyClass: def __init__(self): self.mydict = {'var1': 'value1', 'var2': 'value2', ...} When I want to get the va

Solution 1:

Using setattr, you can set attribute dynamically:

>>>classMyClass:...def__init__(self):...        mydict = {'var1': 'value1', 'var2': 'value2'}...for key, value in mydict.items():...setattr(self, key, value)...>>>instance = MyClass()>>>instance.var1
'value1'
>>>instance.var2
'value2'

Solution 2:

You could add an additional function to the class that will be able to parse the dict and insert the relevant attributes:

defassign_variables( self ):
  for key, val in self.mydict.items():
    setattr( self, key, val )

I'm using the built-in setattr() function here to set attributes with dynamic names/values:

This is the counterpart of getattr(). The arguments are an object, a string and an arbitrary value. The string may name an existing attribute or a new attribute. The function assigns the value to the attribute, provided the object allows it. For example, setattr(x, 'foobar', 123) is equivalent to x.foobar = 123.

You can call this function inside your constructor after the mydict variable is defined or even just place the loop in the constructor.

Solution 3:

Another solution is to implement __getattr__:

classMyClass(object):
    def__init__(self):
        self.mydict = {'var1': 'value1', 'var2': 'value2', ...}

    def__getattr__(self, name):
        try:
            return self.mydict[name]
        except KeyError:
            raise AttributeError("object %s has no attribute '%s'" % (self, name))

Solution 4:

You can directly update the __dict__ attribute of your object I believe:

classMyClass:def__init__(self):
        self.mydict = {'var1': 'value1', 'var2': 'value2', ...}
        self.__dict__.update(self.mydict)

Solution 5:

Another way would be to override __getattr__ and __setattr__ together, which avoids having two object references to the same attribute in the class instance object (one O.R. to value1 inside myobj.mydict['var1'], and another O.R. to value1 in myobj.__dict__['var1']):

classMyClass():
    def__init__(self):
        self.__dict__['_mydict'] = {'var1': 'value1', 'var2': 'value2'}
    #Note: using the @property (descriptor) is optional. I think it makes #things more convenient.    @propertydefmydict(self):
        return self._mydict
    #NOTE: __getattr__ won't get called if att is found in self.__dict__ first! def__getattr__(self,att):
        if att in self.mydict:       # or without using @property: if att in self._mydict:return self.mydict[att]  #                                  return self._mydict[att]else:
            raise AttributeError("'{n}' object has no attribute '{a}'".format(n = type(self).__name__, a = att))
    def__setattr__(self,att,val):
        super().__setattr__(att, val)
        if att in self.mydict:
            self.mydict[att] = val   # or without using @property: self._mydict[att] = val
            self.__delattr__(att)    # remove duplicate copy of object reference to att

Note that doing it this way means you cannot add more key,value pairs to mydict unless you call the property directly, e.g.:

myobj = MyClass()
myobj.x = 1
myobj.mydict #note that result does not contain an entry for 'x'
myobj.mydict['x'] = 2
myobj.mydict #now it does

Also note that getting and deleting the mydict members will be overridden by any existing attribute of the same name (not only that, but you can't delete mydict members at all unless you also override __delattr__ to enable this behavior):

#continuing the above code sessionassert myobj.x == 1#myobj.x is coming from self.x, not from self._mydict['x']
myobj.var1 = 'a new value'
myobj.var1 #results in 'a new value' as expected, but where is it coming from? assert myobj.mydict['var1'] == 'a new value'#Ah: it's coming from self._mydict as expectedassert myobj.__dict__['var1'] #ERROR, as expecteddel myobj.x
assert myobj.x == 2#now myobj.x is coming from self._mydict['x'], self.x having been deleteddel myobj.var1 #raises AttributeError; attributes in mydict can't be deleted (unless you also override __delattr__

If you want to change this behavior, you have to override __getattribute__ (EDIT: which, as bruno desthuilliers notes below, is usually not a good idea).

Post a Comment for "Convert Dict Attributes In Multiple Attributes In Python"