从字符串创建一个函数对象

时间:2011-05-23 13:45:06

标签: python code-generation function-object

问题:有没有办法在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在能够完成这种专长方面远非令人满意。我需要能够实现多种功能的东西。有没有其他方法可以做到这一点,除了那些不涉及将其写入磁盘?我再次尝试动态功能对象

P:是的,我知道这有可怕的安全和稳定性问题。是的,我知道这是一种非常有效的方法。我关心的?没有。这是一个概念证明。 “可以python这样做吗?它能动态创建功能对象”是我想知道的,而不是一些优越的选择。 (尽管在你回答了手头的问题之后,你可以随意使用优质替代品)

3 个答案:

答案 0 :(得分:20)

以下内容将您在字符串中定义的符号放在字典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'的输出。

答案 1 :(得分:0)

如果它只是概念证明,那么eval和exec就可以了,你也可以用pickle字符串,yaml字符串和你决定为其编写构造函数的任何其他东西来做。

答案 2 :(得分:0)

你不能做这样的事吗?

>>> 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'

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