12

问题:有没有办法在 python 中使用字符串创建函数对象?


信息:我正在开发一个将数据存储在 sqlite3 服务器后端的项目。没什么可疯狂的。DAL 类通常通过代码生成来完成,因为代码非常平凡。但这给了我一个想法。在python中,当找不到属性时,如果您定义函数__getattr__,它将在出错之前调用它。所以我想它的方式是,通过解析器和逻辑树,我可以在第一次调用时动态生成我需要的代码,然后将函数对象保存为本地属性。例如:

DAL.getAll()

#getAll() not found, call __getattr__

DAL.__getattr__(self,attrib)#in this case attrib = getAll

##parser logic magic takes place here and I end up with a string for a new function

##convert string to function

DAL.getAll = newFunc

return newFunc

我已经尝试过编译功能,但是就能够完成这种壮举而言,exec 和 eval 还远远不能令人满意。我需要允许多行功能的东西。除了那些不涉及将它写入磁盘的方法之外,还有其他方法可以做到这一点吗?我再次尝试动态创建一个函数对象

PS:是的,我知道这存在可怕的安全性和稳定性问题。是的,我知道这是一种非常低效的方法。我关心的?不。这是一个概念证明。“python可以做到这一点吗?它可以动态创建一个函数对象吗?” 是我想知道的,而不是一些更好的选择。(尽管在您回答了手头的问题后,您可以随意选择更好的替代方案)

4

3 回答 3

26

以下将您在字符串中定义的符号放入字典中d

d = {}
exec "def f(x): return x" in d

现在d['f']是一个函数对象。如果您想在字符串中的代码中使用程序中的变量,可以通过以下方式发送d

d = {'a':7}
exec "def f(x): return x + a" in d

现在 d['f']是一个动态绑定到的函数对象d['a']。当你改变时d['a'],你改变了d['f']().

于 2011-05-23T14:38:55.390 回答
2

你不能做这样的事情吗?

>>> def func_builder(name):
...  def f():
...   # multiline code here, using name, and using the logic you have
...   return name
...  return f
... 
>>> func_builder("ciao")()
'ciao'

基本上,组装一个真正的函数,而不是组装一个字符串,然后尝试将其编译成一个函数。

于 2011-05-23T14:43:33.873 回答
0

如果它只是概念证明,那么 eval 和 exec 就可以了,您也可以使用 pickle 字符串、yaml 字符串以及您决定为其编写构造函数的任何其他内容来执行此操作。

于 2011-05-23T13:49:45.830 回答