Python的eval()和globals()

时间:2009-04-08 09:30:31

标签: python eval

我正在尝试使用eval()执行许多函数,我需要为它们创建一些运行环境。在文档中可以说你可以将全局变量作为第二个参数传递给eval()。

但似乎在我的情况下不起作用。这是一个简单的例子(我尝试了两种方法,声明变量global和使用globals(),两者都不起作用):

文件 script.py

import test

global test_variable
test_variable = 'test_value'
g = globals()
g['test_variable'] = 'test_value'
eval('test.my_func()', g)

文件 test.py

def my_func():
    global test_variable
    print repr(test_variable)

我得到了:

  

NameError:未定义全局名称“test_variable”。

如何将test_variable传递给my_func()?假设我无法将其作为参数传递。

2 个答案:

答案 0 :(得分:10)

test_variable 在test.py中应该是全局的。你得到一个名称错误,因为你试图声明一个尚不存在的变量全局。

所以你的my_test.py文件应该是这样的:

test_variable = None

def my_func():
    print test_variable

从命令提示符运行:

>>> import my_test
>>> eval('my_test.my_func()')
None
>>> my_test.test_variable = 'hello'
>>> my_test.test_variable
'hello'
>>> eval('my_test.my_func()')
hello

一般来说,使用eval()和全局变量是不好的形式,所以一定要知道你在做什么。

答案 1 :(得分:4)

如果我错了,请纠正我的Python专家。我也在学习Python。以下是我目前对为什么抛出NameError异常的理解。

在Python中,您无法创建可以跨模块访问的变量而无需指定模块名称(即访问模块test中的全局变量mod1,您需要使用mod1.test当你在模块mod2中)。全局变量的范围几乎仅限于模块本身。

因此当你在test.py中跟随时:

def my_func():
    global test_variable
    print repr(test_variable)

test_variable此处引用test.test_variable(即test_variable模块命名空间中的test

因此在test_variable中设置script.py会将变量放在__main__命名空间(__main__中,因为这是您提供给Python解释器的顶级模块/脚本执行)。因此,此test_variable将位于不同的命名空间中,而不是在test模块命名空间中。因此,Python生成NameError,因为它在搜索test模块全局命名空间和内置命名空间后找不到变量(由于global语句而跳过了本地函数命名空间)。 / p>

因此,要使eval生效,您需要在test_variable中的test模块命名空间中设置script.py

import test
test.test_variable = 'test_value'
eval('test.my_func()')

有关Python范围和命名空间的更多详细信息,请参阅:http://docs.python.org/tutorial/classes.html#python-scopes-and-name-spaces