我正在尝试使用eval()执行许多函数,我需要为它们创建一些运行环境。在文档中可以说你可以将全局变量作为第二个参数传递给eval()。
但似乎在我的情况下不起作用。这是一个简单的例子(我尝试了两种方法,声明变量global和使用globals(),两者都不起作用):
import test
global test_variable
test_variable = 'test_value'
g = globals()
g['test_variable'] = 'test_value'
eval('test.my_func()', g)
def my_func():
global test_variable
print repr(test_variable)
我得到了:
NameError:未定义全局名称“test_variable”。
如何将test_variable
传递给my_func()
?假设我无法将其作为参数传递。
答案 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