从字符串创建函数对象

Nar*_*ser 8 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
Run Code Online (Sandbox Code Playgroud)

我已经尝试过编译功能,但exec和eval在能够完成这种壮举方面远非令人满意.我需要能够实现多种功能的东西.还有另一种方法可以做到这一点,除了那些不涉及将其写入磁盘?我再次尝试动态创建一个函数对象.

PS:是的,我知道这有可怕的安全和稳定性问题.是的,我知道这是一种非常有效的方法.我关心的?没有.这是一个概念证明."可以python这样做吗?它能动态创建一个函数对象 "是我想知道的,而不是一些优越的选择.(尽管在你回答了手头的问题之后可以自由地选择优秀的替代方案)

Gur*_*geh 22

下面将您在字符串中定义的符号放在字典d中:

d = {}
exec "def f(x): return x" in d
Run Code Online (Sandbox Code Playgroud)

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

d = {'a':7}
exec "def f(x): return x + a" in d
Run Code Online (Sandbox Code Playgroud)

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

  • 正如S.Lott所说,如果你只运行没有"in"的exec,你将在当前的命名空间中获得一个新函数.exec"def f(x):return x"将为您提供一个新的函数对象f,随时可以在您的代码中使用. (2认同)
  • 请注意,对于 Python 3+,您需要 `exec(string, d)`(它是一个函数,就像现在的 `print`);看到这个关于 Py2 与 3 差异的问题:/sf/ask/1056022831/。 (2认同)