解析Python文件并评估所选函数

时间:2011-01-10 18:30:04

标签: python parsing abstract-syntax-tree

我有一个包含多个python函数的文件,每个函数都有一些语句。

def func1():
    codeX...
def func2():
    codeY...

codeX和codeY可以是多个语句。我希望能够解析文件,按名称查找函数,然后评估该函数中的代码。

使用ast模块,我可以解析文件,找到FunctionDef对象,并获取Stmt对象列表,但是如何将其转换为可以传递给eval的字节码?我应该使用编译模块还是解析器模块?

基本上,函数defs仅用于创建单独的代码块。我希望能够获取给定名称的任何代码块,然后在eval中执行该代码(提供我自己的本地/全局范围对象)。如果有更好的方法来做到这一点,我所描述的也会有所帮助。

由于

3 个答案:

答案 0 :(得分:2)

  

我希望能够获取给定名称的任何代码块,然后执行该代码...(提供我自己的本地/全局范围对象)。

天真的解决方案看起来像这样。这是基于假设函数并非都依赖于全局变量。

from  file_that_contains_several_python_functions import *
Direction = some_value
func1()
func2()
func3()

完全按照您的意愿行事。

然而,如果你的所有功能都依赖于全局变量 - 一种让人想起1970年代FORTRAN的设计 - 那么你必须做一些稍微复杂的事情。

 from  file_that_contains_several_python_functions import *
 Direction = some_value
 func1( globals() )
 func2( globals() )
 func3( globals() )

你必须重写所有这些全局使用函数。

 def func1( context )
     globals().update( context )
     # Now you have access to all kinds of global variables

这看起来很难看,因为它是。完全依赖全局变量的函数并不是最好的主意。

答案 1 :(得分:1)

如果您使用的是Python 2.6或更高版本,那么compile()函数除了源代码外还接受AST对象。

>>> import ast
>>> a = ast.parse("print('hello world')")
>>> x = compile(a, "(none)", "exec")
>>> eval(x)
hello world

这些模块都已针对Python 3重新安排。

答案 2 :(得分:1)

使用Python 2.6.4:

text = """
def fun1():
    print 'fun1'

def fun2():
    print 'fun2'

"""

import ast
tree = ast.parse(text)
# tree.body[0] contains FunctionDef for fun1, tree.body[1] for fun2

wrapped = ast.Interactive(body=[a.body[1]])
code = compile(wrapped, 'yourfile', 'single')
eval(code)
fun2() # prints 'fun2'

看看ast doc中的语法:http://docs.python.org/library/ast.html#abstract-grammar。顶级语句必须是Module,Interactive或Expression,因此您需要将函数def包装在其中一个中。