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