Python 的 eval() 和 globals()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/729248/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 20:45:28  来源:igfitidea点击:

Python's eval() and globals()

pythoneval

提问by Andrey

I'm trying to execute a number of functions using eval(), and I need to create some kind of environment for them to run. It is said in documentation that you can pass globals as a second parameter to eval().

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

But it seems to not work in my case. Here's the simpified example (I tried two approaches, declaring variable global and using globals(), and both do not work):

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

File script.py:

文件脚本.py

import test

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

File test.py:

文件test.py

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

And I'm getting:

我得到:

NameError: global name 'test_variable' is not defined.

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

What should I do to pass that test_variableinto my_func()? Assuming I can't pass it as a parameter.

我该怎么做才能将其传递test_variablemy_func()?假设我不能将它作为参数传递。

回答by monkut

test_variableshould be global in test.py. You're getting a name error because you're trying to declare a variable global that doesn't yet exist.

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

So your my_test.py file should be like this:

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

test_variable = None

def my_func():
    print test_variable

And running this from the command prompt:

并从命令提示符运行它:

>>> 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

Generally it's bad form to use eval() and globals, so make sure you know what your doing.

通常,使用 eval() 和 globals 是不好的形式,因此请确保您知道自己在做什么。

回答by maxyfc

Please correct me Python experts if I am wrong. I am also learning Python. The following is my current understanding of why the NameErrorexception was thrown.

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

In Python, you cannot create a variable that can be access across modules without specifying the module name (i.e. to access the global variable testin module mod1you need to use mod1.testwhen you in module mod2). The scope of the global variable is pretty much limited to the module itself.

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

Thus when you have following in test.py:

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

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

The test_variablehere refers to test.test_variable(i.e. test_variablein the testmodule namespace).

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

So setting test_variablein script.pywill put the variable in the __main__namespace (__main__because this is the top-level module/script you provided to the Python interpreter to execute). Thus, this test_variablewill be in a different namespace and not in the testmodule namespace where it is required to be. Hence, Python generates a NameErrorbecause it cannot find the variable after searching the testmodule global namespace and built-in namespace (local function namespace is skipped because of the globalstatement).

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

Therefore, for evalto work, you need to set test_variablein the testmodule namespace in script.py:

因此,为了eval工作,您需要test_variabletest模块命名空间中设置script.py

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

For more details about Python's scope and namespaces see: http://docs.python.org/tutorial/classes.html#python-scopes-and-name-spaces

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