为什么不应该在调用代码的命名空间中使用 exec?使用 exec 设置 class 个实例属性

why exec should never be used in the calling code's namespace? setting class instance attributes with exec

我搜索了论坛,但找不到我要找的东西。 我有这段代码,其中我在 class(超过 300 行)中有很多属性,因为它是一个包含很多东西的图形用户界面。因此,我用 exec 创建了一个可以动态设置属性的函数。

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)
    ...

但是,我不确定这是不是一种非常 pythonic 的方式,我不太了解 exec 周围的注意事项,我不确定 'self' 中的属性是否正确实例化。

我在这里 https://lucumr.pocoo.org/2011/2/1/exec-in-python/ 看到我可以在字典中执行 exec :

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

但我想实现 class 具有 tkinter 功能的实例属性...

我还在另一个 post 中看到他们使用 types.MethodType。我应该使用 types.MethodType(self.{name}chk.set(self.chaines01[0][{chain_index}]), self) 吗? def_attributes 函数中的每个属性?或者 types.DynamicClassAttribute?

我怎样才能用更像 pythonic 的函数替换 exec,它可以在不使用 exec 的情况下与 exec 执行相同的操作?

查看 How is types.MethodType used? 似乎我无法将属性分配给具有 types.MethodType 的 class 实例,因为它需要一个可调用对象。

查看 似乎 DynamicClassAttribute 用于元class 属性问题并且不会用于将属性接地到 'self'。

我尝试在测试类中使用 self.attribute= 和 setattr(self,attribute,value) 执行 exec,并且属性设置正确。

但是我读过 exec 不应该在调用代码的命名空间中使用。

我终于找到了避免 exec 与本地命名空间冲突的好方法:

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

效果很好