2012-07-25 103 views
0

我认为下面的代码完全描述了这个问题。为什么在Test2函数中x没有被定义?为什么Test3函数不会返回错误?python的exec函数的奇怪行为

>>> 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 
+2

你想做什么?不要使用'global',也不要使用'exec';他们导致设计糟糕的代码,而在'exec'中,代码不安全。 – 2012-07-25 21:37:32

+0

我试图从txt文件加载我的基于字典的databese :) – 2012-07-25 21:51:18

+0

是的,不要这样做。相反,将数据库存储为JSON,并使用'mydata = json.load(open('mydb.txt'))'加载它'' – 2012-07-25 21:53:08

回答

2

通过@SanSS给出的答案是正确的,是@Colin Dunklau的评论,但我想补充一个有点更多信息。有一件事可能会让你感到沮丧,那就是Test2中的global x确实是而不是带入执行代码。所以exec创建一个本地变量x,而print x试图读取一个全局变量。这两个例子可能会有所帮助。 。 。

这里通过传递一个快译通,你告诉EXEC使用,作为全局当地人,所以EXEC分配到全局:

>>> def Test2(): 
...  global x 
...  exec 'x=2' in globals() 
...  print(str(x)) 
>>> Test2() 
2 

这里通过在EXEC-ED代码全局声明,你让EXEC分配给全球,其打印语句然后读取:

>>> def Test2(): 
...  global x 
...  exec('global x; x=2') 
...  print(str(x)) 
>>> Test2() 
2 

再次重申,但是,它通常不使用exec一个好主意。有时候,为了理解Python的工作方式,玩弄这样的东西可能会很好,但是很少有这样的情况,这是一种用代码实际完成某些事情的好方法。

3

在功能Test2,当你声明global x就表示x是一个全局变量,所以Python会在全局命名空间为它进行搜索。 由于在全局命名空间中没有定义x变量,所以引发了NameError

如果你读the official documentation你可以看到eval功能不受影响由global语句,所以在Test2exec是创建一个名为x值为2新的本地变量,但不是全球性的; printglobal语句的影响,并在其不存在的全局名称空间中搜索x。在Test3的该x=2语句受global声明从而创建名为x与值全局变量2.

+0

我不明白:(为什么Test3函数工作?exec('x = 2')应该与x = 2 – 2012-07-25 21:49:06

+1

@ user1354439相同,请参阅我的回答以获得解释。全局语句不会执行到执行代码,所以'exec('x = 2')'是不一样的作为'x = 2' – BrenBarn 2012-07-25 21:53:51

+0

@BrenBarn我在编辑我的评论,以解释当你回答时,我无法像你那样简单地解释它:P – 2012-07-25 21:58:27