【发布时间】:2019-08-17 05:42:07
【问题描述】:
长话短说,我正在对 python 中的方法进行一些动态属性注入测试。
现在我遇到的问题是,当我在 getter 和 setter 字符串上调用 exec() 以将它们转换为动态创建的函数时,它们仍然是字符串。
def _injectProperties(self):
"""docstring"""
for p in self.InputParameters:
index = p.Order
name = p.Name.lstrip('@')
pName = p.Name
fnGet = (
"def get(self): \n"
" rtnVal = [p.Value for p in self.InputParameters "
" if p.Name == '{0}'][0] \n"
" return rtnVal ").format(p.Name)
fnSet = (
"def set(self, value): \n"
" prop = [p for p in self.InputParameters "
" if p.Name == '{0}'][0] \n"
" prop.Value = value \n"
" return ").format(p.Name)
exec(fnGet) in locals()
exec(fnSet) in locals()
self._addprop(name, fnGet, fnSet)
return
所以基本上在上面的代码中_addprop 是一个简单地创建类的副本并为其设置属性的函数:
setattr(cls, name, property(fget=getter, fset=setter, fdel=destructor, doc=docstring))
为什么在这种情况下fnGet 和fnSet 变量在我调用exec(fnGet) 和exec(fnSet) 之后仍然引用get 和set 函数的字符串表示形式?
【问题讨论】:
-
把 exec 改成 setattr(object, funname, anonymous_function)
-
您为什么希望
exec将您的fnGet和fnSet变量转换为(我假设的)函数? -
顺便说一句,
exec <code> in <scope>语法已在 python 3 中删除。您应该使用exec(<code>, <scope>)。 -
只有当你的字符串变量与函数同名时才会发生这种情况。在这种情况下,函数定义会覆盖变量。但是你的函数被命名为
get/set,而不是fnGet/fnSet。 -
@JamieMarshall 反正没必要这么麻烦。您可以定义
__getattr__来处理未定义的属性,而不是执行添加方法。
标签: python python-3.x properties setter getter