python为什么修改全局的dict变量不用global关键字

Posted 匡子语

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python为什么修改全局的dict变量不用global关键字相关的知识,希望对你有一定的参考价值。

转自:http://my.oschina.net/leejun2005/blog/145911?fromerr=qnPCgI19#OSC_h4_8

 

为什么修改字典d的值不用global关键字先声明呢?

s = foo
d = {a:1}
def f():
    s = bar
    d[b] = 2
f()
print s  # foo
print d  # {‘a‘: 1, ‘b‘: 2}

这是因为,在s = ‘bar‘这句中,它是“有歧义的“,因为它既可以是表示引用全局变量s,也可以是创建一个新的局部变量,所以在python中,默认它的行为是创建局部变量,除非显式声明global,global定义的本地变量会变成其对应全局变量的一个别名,即是同一个变量。

在d[‘b‘]=2这句中,它是“明确的”,因为如果把d当作是局部变量的话,它会报KeyError,所以它只能是引用全局的d,故不需要多此一举显式声明global。

上面这两句赋值语句其实是不同的行为,一个是rebinding(不可变对象), 一个是mutation(可变对象).

但是如果是下面这样:

d = {a:1}
def f():
    d = {}
    d[b] = 2
f()
print d  # {‘a‘: 1}

在d = {}这句,它是”有歧义的“了,所以它是创建了局部变量d,而不是引用全局变量d,所以d[‘b‘]=2也是操作的局部变量。

推而远之,这一切现象的本质就是”它是否是明确的“

仔细想想,就会发现不止dict不需要global,所有”明确的“东西都不需要global。因为int类型str类型之类的不可变对象,每一次操作就重建新的对象,他们只有一种修改方法,即x = y, 恰好这种修改方法同时也是创建变量的方法,所以产生了歧义,不知道是要修改还是创建。而dict/list/对象等可变对象,操作不会重建对象,可以通过dict[‘x‘]=y或list.append()之类的来修改,跟创建变量不冲突,不产生歧义,所以都不用显式global。

以上是关于python为什么修改全局的dict变量不用global关键字的主要内容,如果未能解决你的问题,请参考以下文章

函数全局变量的修改

python 多进程共享全局变量之Manager()

Python实现跨文件全局变量的方法(2文件优化版)

python引用局部变量之nonlocal

如何为仅更新全局dict类型变量的函数编写unit_test-Python(pytest)

Python中全局变量的引用与修改之格式影响