8

我正在尝试使用 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_variablemy_func()?假设我不能将它作为参数传递。

4

2 回答 2

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() 和全局变量是不好的形式,因此请确保您知道自己在做什么。

于 2009-04-08T09:32:51.280 回答
4

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

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

因此,当您有以下内容时test.py

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

这里test_variable指的是test.test_variable(即test_variabletest模块命名空间中)。

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

因此,为了eval工作,您需要test_variabletest模块命名空间中设置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

于 2009-04-08T10:44:36.287 回答