Skip to content
Advertisement

python assign attribute names and his values with a dictionary passed to the class

The normal way to pass a variable to a class atrubte is as follows:

class makeGUI():
    def __init__(self,a):
        self.a = a

It is a convention to call the variable inside the init the same as the attribute. I could have done:

class makeGUI2():
    
    def __init__(self,a):
        self.b = a

Now imagine I would like to pass to the init method a dictionary with the name of the attributes and the values they should take. I tried the following:

class makeGUI3(): 
    def __init__(self,**Kwargs):
        for key,value in Kwargs.items():
            print(key,value)
            print(f'self.{key}={value}')
            exec(f'self.{key}={value}')
C = makeGUI3({'c':1234,'d':4567,'e':4567})

This works as far as the values are of the type int. C has three attributes called c,d,e with the corresponding values.

Nevertheless this fails when the value passed are not of the type int:

C = makeGUI3({'c':(1,2),'d':'lalala','e':[4,5,6,7]}) # does not work.

this last line results in:

c (1, 2)
self.c=(1, 2)
d lalala
self.d=lalala
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-22-c9ae5d10f250> in <module>
----> 1 C = makeGUI3({'c':(1,2),'d':'lalala','e':[4,5,6,7]})

<ipython-input-14-a67330a26e5d> in __init__(self, mydict)
      4             print(key,value)
      5             print(f'self.{key}={value}')
----> 6             exec(f'self.{key}={value}')

<string> in <module>

NameError: name 'lalala' is not defined

I would like that the class constructor is agnostic to the kind of data passed.

I know the use of exec is not recommended but I don’t find another way. Besides if there would be a proper way of doing this any object might be passed to the class constructor. As you can guess by the name of the class the idea is being able to pass elements to construct a widget collection inside of a class.

thx.

Advertisement

Answer

Use setattr.

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.

class makeGUI3(): 
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement