Python 如何使用AST将文本编译为函数?
我需要编译一个输入字符串(来自数据库)作为函数并运行它。这是我目前使用的方法: 假设我已经定义了此函数:Python 如何使用AST将文本编译为函数?,python,exec,abstract-syntax-tree,Python,Exec,Abstract Syntax Tree,我需要编译一个输入字符串(来自数据库)作为函数并运行它。这是我目前使用的方法: 假设我已经定义了此函数: def foo(): print "Yo foo! I am a function!" 我从数据库中读取的字符串说我应该调用这个函数: string_from_db = "foo()" 然后,我形成一个函数(其名称我可以控制),该函数返回我从数据库读入的函数: my_func_string = "def doTheFunc():\n\t return " + string_fro
def foo():
print "Yo foo! I am a function!"
我从数据库中读取的字符串说我应该调用这个函数:
string_from_db = "foo()"
然后,我形成一个函数(其名称我可以控制),该函数返回我从数据库读入的函数:
my_func_string = "def doTheFunc():\n\t return " + string_from_db
现在我编译字符串,并将其设置为稍后用于处理的函数名:
exec my_func_string
processor = doTheFunc
我可以稍后通过运行processor()
调用它,它会惊呼:yofoo!我是一个函数代码>
我的问题:在这段代码上面有一条评论(由一位失散多年的开发人员留下):
我想知道更多关于这个“潜在替代品”的信息。我已经看过AST,但是我很困惑它如何帮助我完成我已经在用上面的代码做的事情
如何使用AST完成同样的事情?或者AST在这个过程中可以在哪里帮助我
使用AST的实现更好吗?为什么
在评估可能包含恶意指令的不可信代码时,AST是一个更安全的选择,eval
或exec
可以执行任何表达式,而另一方面,AST允许您自己解析和验证表达式,或使用AST.literal\u eval
执行有限的表达式,有点像沙箱,只允许字符串、列表、数字和其他一些东西。这只是一个简单的例子:
import ast
a = ast.literal_eval("[1,2,3,4]") //evaluate an expression safely.
将字符串解析为AST的另一个示例:
import ast
source = '2 + 2'
node = ast.parse(source, mode='eval')
ast.dump(node)
这张照片是:
Expression(body=BinOp(left=Num(n=2), op=Add(), right=Num(n=2)))
这里有一个非常好的教程,还有你可能会在黑暗魔法的领域。如果你知道字符串是安全的,就没有理由在exec()上使用ast
。Python解释器已经实现了将Python源代码解析为函数对象,为什么要复制它?@millimoose我最终使用了exec
实现,因为我知道我的字符串是安全的。然而,这个问题启发了我如何更好地使用ast
。谢谢很棒的教程!我将如何“为自己验证表达式”?我如何判断代码是坏的,还是不符合我的要求?假设我需要编译小函数;我不能把自己局限于简单的字符串、列表等。@babydanks你可以发现它是否调用了任何不应该调用的函数,比如open
也许。啊!在什么级别上最容易做到这一点?一旦有了ast功能节点?(也就是说,检查open
最简单的方法是什么?)@babydanks有一个NodeVisitor
类,你可能应该看看,教程中也有一个例子。@babydanks重点是,它让你对执行什么和不执行什么有更多的控制,而不是eval
或exec
(如果需要)。
Expression(body=BinOp(left=Num(n=2), op=Add(), right=Num(n=2)))