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()
有效。
答案 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中有本地(默认)和全局上下文。为每个函数单独初始化一个新的本地上下文,当函数启动时它是空的。全局上下文是全局的,并且(几乎)模块的每个部分共享。
通过使用全局指令,您可以从全局上下文导入变量,从而阻止在本地变量中进行符号查找(这是空的,否则会失败)。