Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用AST将文本编译为函数?_Python_Exec_Abstract Syntax Tree - Fatal编程技术网

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