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

2024-05-15 13:19:59 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

Tags: 函数testdef语句myfuncglobal例子exec
3条回答

每个the docsexec语句接受两个可选表达式,默认为globals()locals(),并且总是在locals()语句中执行更改(如果有)。

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

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

……你就可以把全局变量敲到你心里的内容。

这个怎么样:

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

它在Python2.6中对我有效。

编辑:事实上亚历克斯·马泰利的解释比我的好得多:)

添加到Alex的答案中:虽然当省略locals/globals参数时,它们默认为调用者的locals和globals,但这只是一个方便的技巧;它确实而不是意味着它们继承了调用者的完整执行上下文。特别是:

a.嵌套的作用域单元格对执行的代码不可用。所以这失败了:

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

b.global声明不会继承到执行的代码中。因此,在默认情况下,就像在您的示例中一样,写入的变量被放入局部变量字典中。但是,你可以说

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

如果你能帮忙的话,你真的不想这么做。global已经不好了,exec本身就是一种代码味道!除非别无选择,否则你不会想把它们结合起来。

相关问题 更多 >