python的全局关键字如何工作?

时间:2014-09-05 03:00:23

标签: python

import json

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

if __name__ == '__main__':
    test()

将抛出异常:

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()

有效。

3 个答案:

答案 0 :(得分:2)

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

该名称在全局范围内也可用并不重要。编译器知道该名称是本地的,并且只在本地范围内查找它。

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

“global”语句意味着,即使在赋值语句中使用此名称,它也不是本地名称,而是全局名称。在第二个函数中,全局语句使名称“json”引用全局“json”,当您尝试访问它时已经定义了它,因此您的函数可以正常工作。

答案 1 :(得分:1)

python首次解析函数代码时会看到import json语句,并确定json是局部变量。 (如果您分配给json,也会发生同样的事情 - 例如json = 'Hello World!')。当表达式json.dumps执行时,python在本地范围内查找json并且找不到它(因此异常)。

在第二种情况下,当您添加global时,在解析函数时,您告诉python始终在全局范围内查找json。在你的情况下,它存在于那里,因为你已经导入它所以这一切都很好。它还告诉python json的任何赋值(或导入)都应该将名称(和相关值)存储在全局范围而不是本地范围中。

答案 2 :(得分:-1)

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

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