我认为下面的代码完全描述了这个问题。为什么在Test2函数x中没有定义?为什么Test3函数不会返回错误?
>>> def Test1():
exec('x=2')
print(str(x))
>>> Test1()
2
>>> def Test2():
global x
exec('x=2')
print(str(x))
>>> Test2()
Traceback (most recent call last):
File "<pyshell#39>", line 1, in <module>
Test2()
File "<pyshell#38>", line 4, in Test2
print(str(x))
NameError: global name 'x' is not defined
>>> def Test3():
global x
x=2
print(str(x))
>>> Test3()
2
答案 0 :(得分:3)
在函数Test2
中,当您声明global x
时,您声明x
是一个全局变量,因此Python将在全局命名空间中搜索它。
由于全局命名空间中没有定义x
变量,因此会引发NameError
。
如果您阅读the official documentation,则可以看到eval
功能不受global
声明影响,因此在Test2
exec
正在创建名为x
的新局部变量,值为2,但不是全局变量; print
受global
语句的影响,并在不存在的全局命名空间中搜索x
。在Test3中,x=2
语句受global
语句的影响,从而创建一个名为x的全局变量,值为2.
答案 1 :(得分:2)
@SanSS给出的答案是正确的,正如@Colin Dunklau的评论一样,但我想补充一点信息。可能会让您失望的一件事是Test2中的global x
不继续执行执行代码。因此,exec创建本地变量x
,而print x
尝试读取全局变量。这两个例子可能会有所帮助。 。
这里通过传递一个dict,你告诉exec使用它作为全局和本地,所以exec分配给全局:
>>> def Test2():
... global x
... exec 'x=2' in globals()
... print(str(x))
>>> Test2()
2
这里通过在exec-ed代码中包含全局声明,将exec赋值给global,然后print语句读取:
>>> def Test2():
... global x
... exec('global x; x=2')
... print(str(x))
>>> Test2()
2
然而,重申一下,使用exec
通常不是一个好主意。有时只是为了理解Python是如何工作的,可以很好地利用这样的东西,但是在很少的情况下,这是用你的代码实际完成某些事情的好方法。