Python AST节点不能在函数内执行

时间:2017-09-16 12:27:09

标签: python python-2.7 abstract-syntax-tree

有人能给我一个关于这种行为的建议吗?下一个代码运行良好:

import ast


node = ast.parse('def nsd(a, b):\n    if b == 0: return a    \n    return nsd(b, a%b)\n\nprint nsd(18,15)')
obj = compile(node, filename="<ast>", mode="exec")
exec obj

但是当我在一个函数中做同样的事情时:

import ast


def foo():
    node = ast.parse('def nsd(a, b):\n    if b == 0: return a    \n    return nsd(b, a%b)\n\nprint nsd(18,15)')
    obj = compile(node, filename="<ast>", mode="exec")
    exec obj

foo()

它引发了一个错误:

Traceback (most recent call last):
  File "C:/Users/Vectoun/PycharmProjects/untitled3/test.py", line 9, in <module>
    foo()
  File "C:/Users/Vectoun/PycharmProjects/untitled3/test.py", line 7, in foo
    exec obj
  File "<ast>", line 5, in <module>
  File "<ast>", line 3, in nsd
NameError: global name 'nsd' is not defined

我希望能够在一个函数中运行它。有谁知道如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

如果我没有弄错的话,这里的问题是,当使用exec时,你仍然被绑定到范围。

因此,在方法之外运行AST代码会将nsd定义为全局方法,而在foo()中运行AST代码会使nsd成为foo的成员直接范围,因此调用将无法查找方法。

您可以先将nsd定义为全局:

来解决此问题
import ast


def foo():
    code = """global nsd
def nsd(a, b):
    if b == 0:
        return a
    return nsd(b, a%b)
print nsd(18,15)
    """
    node = ast.parse(code)
    obj = compile(node, filename="<ast>", mode="exec")
    exec obj

foo()