python 无法通过 exec() 语句更改函数中的全局变量?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2083353/
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 23:43:42  来源:igfitidea点击:

Cannot change global variables in a function through an exec() statement?

pythonexecglobal

提问by linkmaster03

Why can I not change global variables from inside a function, using exec()? It works fine when the assignment statement is outside of exec(). Here is an example of my problem:

为什么我不能使用 exec() 从函数内部更改全局变量?当赋值语句在 exec() 之外时它工作正常。这是我的问题的一个例子:

>>> myvar = 'test'
>>> def myfunc():
...     global myvar
...     exec('myvar = "changed!"')
...     print(myvar)
... 
>>> myfunc()
test
>>> print(myvar)
test

回答by Alex Martelli

Per the docs, the execstatement takes two optional expressions, defaulting to globals()and locals(), and always performs changes (if any) in the locals()one.

根据docs,该exec语句采用两个可选表达式,默认为globals()and locals(),并且始终在其中执行更改(如果有)locals()

So, just be more explicit/specific/precise...:

所以,只要更明确/具体/精确...:

>>> def myfunc():
...   exec('myvar="boooh!"', globals())
... 
>>> myfunc()
>>> myvar
'boooh!'

...and you'll be able to clobber global variables to your heart's contents.

...并且您将能够将全局变量破坏为您心中的内容。

回答by bobince

To add to Alex's answer: although when you omit the locals/globals arguments they default to the locals and globals of the caller, this only a convenience hack; it does notmean they are inheriting the full execution context of the caller. In particular:

添加到 Alex 的答案:虽然当您省略 locals/globals 参数时,它们默认为调用者的 locals 和 globals,但这只是一个方便的黑客;它意味着他们继承呼叫者的全面执行上下文。特别是:

a. nested scope cells are not available to the execed code. So this fails:

一个。嵌套的作用域单元不适用于 execed 代码。所以这失败了:

def f():
    foo= 1
    def g():
        exec('print foo')
    g()
f()

b. globaldeclarations do not carry over into the execed code. So by default as in your example, written variables are put in the locals dictionary. However, you could make it work by saying

global声明不会延续到 execed 代码中。因此,在您的示例中,默认情况下,写入的变量放在 locals 字典中。但是,您可以通过说使其工作

exec('global myvar\nmyvar = "changed!"')

You don't really want to be doing this if you can help it. globalalready isn't nice and execis pretty much a code smell in itself! You wouldn't want to combine them unless there was really no alternative.

如果你能帮上忙,你不会真的想这样做。global已经不好了,而且exec本身就是一种代码气味!除非真的别无选择,否则您不会想要将它们组合起来。

回答by Attila O.

How about this:

这个怎么样:

>>> myvar = 'test'
>>> def myfunc():
...     exec('globals()["myvar"] = "changed!"')
...     print(myvar)
... 
>>> myfunc()
changed!
>>> print(myvar)
changed!

It worked for me in Python 2.6.

它在 Python 2.6 中对我有用。

EDIT: Actually Alex Martelli's explanation is much better than mine :)

编辑:实际上 Alex Martelli 的解释比我的好得多:)