可能重复:
为什么不是关键字global在此情况下需要?
我不知道为什么我可以改变全局字典没有global
的关键字? 为什么它是强制性的其它类型的? 有这背后的任何逻辑?
例如代码:
#!/usr/bin/env python3
stringvar = "mod"
dictvar = {'key1': 1,
'key2': 2}
def foo():
dictvar['key1'] += 1
def bar():
stringvar = "bar"
print(stringvar)
print(dictvar)
foo()
print(dictvar)
print(stringvar)
bar()
print(stringvar)
给出了以下结果:
me@pc:~/$ ./globalDict.py
{'key2': 2, 'key1': 1}
{'key2': 2, 'key1': 2} # Dictionary value has been changed
mod
bar
mod
在那里我会想到:
me@pc:~/$ ./globalDict.py
{'key2': 2, 'key1': 1}
{'key2': 2, 'key1': 1} # I didn't use global, so dictionary remains the same
mod
bar
mod
原因是该行
stringvar = "bar"
是模糊的,也可能是指一个全局变量, 或者它可以被称为创建新的本地变量stringvar
。 在这种情况下,Python的默认假设它是一个局部变量,除非global
的关键字已经被使用。
然而,行
dictvar['key1'] += 1
完全是毫不含糊的。 它可以只提到全局变量dictvar
,因为dictvar
必须已经存在,不会引发错误的语句。
这是不特定的dictionaries-也是一样名单:
listvar = ["hello", "world"]
def listfoo():
listvar[0] = "goodbye"
或其他类型的对象:
class MyClass:
foo = 1
myclassvar = MyClass()
def myclassfoo():
myclassvar.foo = 2
每当这是真的变异操作中使用,而不是重新绑定一个 。
您可以修改任何可变对象,而无需使用global
关键字。
因为这是在Python可能global
的时候要重新分配新的对象,以在全球范围内已经使用的变量名,或者定义新的全局变量使用。
但你不重新分配任何可变对象的情况下,你只是修改他们原地的,因此Python中简单地从全局范围内进行加载和修改它们。
作为文档说:
这将是不可能分配到一个全局变量没有全局。
In [101]: dic = {}
In [102]: lis = []
In [103]: def func():
dic['a'] = 'foo'
lis.append('foo') # but fails for lis += ['something']
.....:
In [104]: func()
In [105]: dic, lis
Out[105]: ({'a': 'foo'}, ['foo'])
dis.dis
:
In [121]: dis.dis(func)
2 0 LOAD_CONST 1 ('foo')
3 LOAD_GLOBAL 0 (dic) # the global object dic is loaded
6 LOAD_CONST 2 ('a')
9 STORE_SUBSCR # modify the same object
3 10 LOAD_GLOBAL 1 (lis) # the global object lis is loaded
13 LOAD_ATTR 2 (append)
16 LOAD_CONST 1 ('foo')
19 CALL_FUNCTION 1
22 POP_TOP
23 LOAD_CONST 0 (None)
26 RETURN_VALUE