python:var的命名空间代码eval编译为ast代码

时间:2014-05-27 14:34:59

标签: python namespaces eval abstract-syntax-tree python-unittest

使用python3.4并测试ast解析。这是测试代码。

import ast
import unittest


class TestAST(unittest.TestCase):

    def test_ast(self):
        #compileobj = compile(ast.parse("x=42"), '<input>', mode="exec")
        #compile(ast.parse("x=42"), '<input>', mode="exec")
        eval(compile(ast.parse("x=42"), '<input>', mode="exec"))
        self.assertTrue(x == 42)
        pass


if __name__ == '__main__':
    unittest.main()

python test.py我收到这样的错误:

Traceback (most recent call last):
  File "qocean\test\test_ast.py", line 13, in test_ast
    self.assertTrue(x == 42)
NameError: name 'x' is not defined

在ipython中评估它时:x可以这样看:

In [3]:  eval(compile(ast.parse("x=42"), '<input>', mode="exec"))

In [4]: x
Out[4]: 42

所以排队是,虽然我不能使用var&#34; x&#34; ,因为源代码和ipython eval environemt中的eval代码相同。有什么区别?

#############################################

更新:似乎它与unittest模块有关,在main()中更改测试代码,它会成功。

if __name__ == '__main__':
    eval(compile(ast.parse("x=42"), '<input>', mode="exec"))
    print (x)
运行后

它显示了42。

更详细,在func中调用此方法也失败了

def test_eval():
    eval(compile(ast.parse("y=42"), '<input>', mode="exec"))
    print ("y is ", y)

if __name__ == '__main__':
    #unittest.main()
    test_eval()

1 个答案:

答案 0 :(得分:2)

在Python 3中,您无法动态创建新的本地名称。这些在函数编译为字节码时被烘焙。相反,您需要将字典传递给exec以在该语句中用作本地语。

def test_ast(self):
    localvars = {}
    eval(compile(ast.parse("x=42"), '<input>', mode="exec"), localvars)
    self.assertTrue(localvars["x"] == 42)