无法通过exec()语句在函数中更改全局变量?
为什么我不能在函数内部通过exec()来改变全局变量?当赋值语句在exec()外面时,一切都正常。下面是我遇到的问题的例子:
>>> myvar = 'test' >>> def myfunc(): ... global myvar ... exec('myvar = "changed!"') ... print(myvar) ... >>> myfunc() test >>> print(myvar) test
4 个回答
4
这样怎么样:
>>> myvar = 'test'
>>> def myfunc():
... exec('globals()["myvar"] = "changed!"')
... print(myvar)
...
>>> myfunc()
changed!
>>> print(myvar)
changed!
在Python 2.6中,这对我有效。
补充:其实Alex Martelli的解释比我的要好得多 :)
5
补充一下Alex的回答:虽然当你省略locals和globals参数时,它们默认使用调用者的locals和globals,但这只是一个方便的小技巧;这并不意味着它们会完全继承调用者的执行环境。特别是:
a. 嵌套作用域的变量在执行的代码中是无法访问的。所以这段代码会失败:
def f():
foo= 1
def g():
exec('print foo')
g()
f()
b. global
声明不会传递到执行的代码中。因此,像你例子中的情况,写入的变量会放在locals字典里。不过,你可以通过这样做来让它生效:
exec('global myvar\nmyvar = "changed!"')
如果可以的话,你其实不太想这样做。global
本身就不太好,而exec
几乎算是一种代码异味!除非真的没有其他选择,否则你不想把它们结合在一起。
41
根据文档,exec
语句可以接受两个可选的表达式,默认情况下是 globals()
和 locals()
,而且总是会在 locals()
中进行更改(如果有的话)。
所以,记得要更明确/具体/精确一些……:
>>> def myfunc():
... exec('myvar="boooh!"', globals())
...
>>> myfunc()
>>> myvar
'boooh!'
…这样你就可以随心所欲地修改全局变量了。