我最近一直在使用Python的AST(抽象语法树)模块,但遇到了一个似乎无法运行import语句的问题。我对此一无所获,也不确定是怎么回事。
使用AST解析.py文件,然后编译/运行树时,树中的import语句似乎被忽略,而有利于脚本中的解析。
这里是该问题的最小工作示例。由extended AST documentation
制成test.py
from random import choice
def ast_broken_demo():
lis = ["foo", "bar"]
print(choice(lis))
ast_broken_demo()
parser.py
import ast
#from random import choice
def main():
path = "test.py"
source_code = open(path).read()
a = ast.parse(source_code)
ast.fix_missing_locations(a)
co = compile(a, '<ast>', 'exec')
print(ast.dump(a))
exec(co)
main()
这会导致错误消息:
Traceback (most recent call last):
File "test.py", line 18, in <module>
main()
File "test.py", line 16, in main
exec(co)
File "<ast>", line 19, in <module>
File "<ast>", line 17, in ast_broken_demo
NameError: name 'choice' is not defined
如果您将from random import choice
放在 parser.py 的顶部,则可以解决此问题,但是我不必这样做,因为确切的行位于 test.py ,并且应在AST运行时执行。将导入放入 parser.py 尤其糟糕,因为解析器应该解析任意的.py文件,因此我无法导入任何人可能使用的所有内容。
这是怎么回事?为什么解析使用错误的导入,或者为什么不运行 test.py 中的import语句?谢谢。