解析Python文件并评估选定函数
我有一个文件,里面包含了几个Python函数,每个函数都有一些语句。
def func1():
codeX...
def func2():
codeY...
codeX和codeY可以有多条语句。我想解析这个文件,通过函数名找到一个函数,然后执行这个函数里的代码。
使用ast模块,我可以解析文件,找到FunctionDef对象,并获取Stmt对象的列表,但我该如何将这些转换成可以传给eval的字节码呢?我应该使用compile模块,还是parser模块呢?
基本上,函数定义只是用来创建独立的代码块。我想根据名字抓取任何代码块,然后在eval中执行这些代码(提供我自己的局部/全局作用域对象)。如果有比我描述的方法更好的做法,那也很有帮助。
谢谢
3 个回答
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
我想要能够根据名称获取任何代码块,然后执行这些代码……(同时提供我自己的本地/全局作用域对象)。
一个简单的解决方案看起来是这样的。这是基于假设这些函数并不都依赖于全局变量。
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
使用 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 文档中的语法:http://docs.python.org/library/ast.html#abstract-grammar。最顶层的语句必须是模块、交互式或表达式之一,所以你需要把函数定义放在这三者中的一个里面。