Home > Back-end >  why exec should never be used in the calling code's namespace? setting class instance attribute
why exec should never be used in the calling code's namespace? setting class instance attribute

Time:03-30

I ve searched the forum but i couldnt exactly find what im looking for. I have this code where i have many attributes in a class (more than 300 lines) because it's a gui with a lot of stuff. I have therefore made a function with exec which can set the attributes dynamically.

MyClass():
    #some code
    def set_attributes(self,name,chain_index):
        exec(f'self.{name}chk.set(self.chaines01[0][{chain_index}])')
        exec(f'self.{name}dateEntry.delete(0, "end")')
        exec(f'self.{name}dateEntry.insert(0, self.listdates[{chain_index}])')
        exec(f'self.{name}commentEntry.delete(0, "end")')
        exec(f'self.{name}commentEntry.insert(0, self.listcomments[{chain_index}])')

    self.set_attributes('attribute1',1)
    self.set_attributes('attribute2',1)
    ...

However, I'm not sure it's a very pythonic way to do and i dont know well the caution around exec and im not sure the attributes are instanciated correctly in 'self'.

I've seen here https://lucumr.pocoo.org/2011/2/1/exec-in-python/ that i could do exec in a dictionnary :

>>> code = compile('a = 1   2', '<string>', 'exec')
>>> ns = {}
>>> exec code in ns
>>> print ns['a']
3

But I want to implement class instance attributes with tkinter features...

I've also seen in another post where they use types.MethodType. Should I use types.MethodType(self.{name}chk.set(self.chaines01[0][{chain_index}]), self) ? on each attributes in the def_attributes function? Or types.DynamicClassAttribute?

How could i replace exec with a more pythonic function that would do the same as exec without using exec?

CodePudding user response:

looking at How is types.MethodType used? it seems i cant assign an attribute to a class instance with types.MethodType as it requires a callable.

looking at What is a DynamicClassAttribute and how do I use it? it seems DynamicClassAttribute is used for metaclass attributes issues and wont be of any use for grounding an attribute to 'self'.

I tried exec in a testClass with self.attribute= and with setattr(self,attribute,value) and the attribute is set properly.

However i ve read exec should never be used in the calling code's namespace.

I have finally found a good way to avoid exec conflicting with local namespaces:

exec(compile(f'self.{name}chk.set(self.chaines01[0][{chain_index}])', '<string>', 'exec')) in self.__dict__

It works fine

  • Related