2014-09-05 68 views
0
import json 

def test(): 
    print json.dumps({'k': 'v'}) 
    import json 

if __name__ == '__main__': 
    test() 

将抛出一个异常:python的全局关键字是如何工作的?

UnboundLocalError: local variable 'json' referenced before assignment 

添加global关键字

import json 

def test(): 
    global json 
    print json.dumps({'k': 'v'}) 
    import json 

if __name__ == '__main__': 
    test() 

它的工作原理。

+1

为什么你需要第二次导入'json'?为什么你需要在第一次使用后让它出现?你为什么需要这么写你的代码? – 2014-09-05 03:05:43

+0

可能的重复? http://stackoverflow.com/q/21978925/748858 - 我敢肯定还有其他人...... – mgilson 2014-09-05 03:13:01

回答

2

对函数名称的任何赋值都会使函数的名称成为本地名称。即使它是函数中的最后一个语句,它在赋值函数中的哪个位置并不重要:名称对于函数是本地的。如果您在分配之前使用本地名称,则会看到您看到的错误。

这个名字在全球范围内也可以使用并不重要。编译器知道这个名字是本地的,只会在本地范围内查找它。

导入语句是一种赋值形式。你在函数中的“import json”语句使得函数名称为“json”。在本地导入之前使用该名称,因此您使用的是未绑定的本地。

“全局”语句表示即使该名称用于赋值语句中,但它不是本地名称,而是全局名称。在第二个函数中,全局语句使得名称“json”引用全局“json”,当您尝试访问它时已经定义了这个全局“json”,所以你的函数可以工作。

1

python在首次解析函数代码时会看到import json声明,并且它决定json是一个局部变量。 (如果你将指定为json - 例如json = 'Hello World!'),将发生同样的事情。当执行表达式json.dumps时,python在本地范围内查找json,并且没有找到它(因此是例外)。

在第二种情况下,当您添加global,当函数解析,你告诉蟒蛇总是寻找json全球范围。在你的情况下,它已经存在,因为你已经导入它,所以它都很好。它还告诉Python,json的任何分配(或导入)都应该在全局范围而不是本地范围中存储名称(和关联值)。

-1

在Python中有本地(默认)和全局上下文。一个新的本地上下文是为每个函数分别初始化的,当函数启动时它是空的。全球背景是全球性的,并且由(几乎)模块的每个部分共享。

通过使用全局指令,您可以从全局上下文中导入一个变量,防止本地符号查找(这是空的,否则会失败)。