Python's eval() and globals()

怎甘沉沦 提交于 2020-01-03 08:34:13

问题


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().

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

File script.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:

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

And I'm getting:

NameError: global name 'test_variable' is not defined.

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


回答1:


test_variable should 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.

So your my_test.py file should be like this:

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.




回答2:


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

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 test in module mod1 you need to use mod1.test when you in module mod2). The scope of the global variable is pretty much limited to the module itself.

Thus when you have following in test.py:

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

The test_variable here refers to test.test_variable (i.e. test_variable in the test module namespace).

So setting test_variable in script.py will 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_variable will be in a different namespace and not in the test module namespace where it is required to be. Hence, Python generates a NameError because it cannot find the variable after searching the test module global namespace and built-in namespace (local function namespace is skipped because of the global statement).

Therefore, for eval to work, you need to set test_variable in the test module namespace in 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



来源:https://stackoverflow.com/questions/729248/pythons-eval-and-globals

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!