Jov*_*vik 32 python dictionary scope global global-variables
可能重复:
为什么在这种情况下不需要全局关键字?
我想知道为什么我可以在没有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)
Run Code Online (Sandbox Code Playgroud)
给出以下结果:
me@pc:~/$ ./globalDict.py
{'key2': 2, 'key1': 1}
{'key2': 2, 'key1': 2} # Dictionary value has been changed
mod
bar
mod
Run Code Online (Sandbox Code Playgroud)
我期待的地方:
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
Run Code Online (Sandbox Code Playgroud)
Dav*_*son 41
原因是这条线
stringvar = "bar"
Run Code Online (Sandbox Code Playgroud)
是不明确的,它可能是指一个全局变量,或者它可能是创建一个名为的新局部变量stringvar
.在这种情况下,Python默认假设它是一个局部变量,除非global
已经使用了该关键字.
但是,行
dictvar['key1'] += 1
Run Code Online (Sandbox Code Playgroud)
完全是毫不含糊的.它只能引用全局变量dictvar
,因为dictvar
语句必须已存在才能抛出错误.
这不是字典特有的 - 列表也是如此:
listvar = ["hello", "world"]
def listfoo():
listvar[0] = "goodbye"
Run Code Online (Sandbox Code Playgroud)
或其他类型的物品:
class MyClass:
foo = 1
myclassvar = MyClass()
def myclassfoo():
myclassvar.foo = 2
Run Code Online (Sandbox Code Playgroud)
每当使用变异操作而不是重新绑定操作时都是如此.
您可以不使用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'])
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
48255 次 |
最近记录: |