全球词典不需要关键字全球对其进行修改? [重复](Global dictionaries don

2019-07-18 05:14发布

可能重复:
为什么不是关键字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

Answer 1:

原因是该行

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

每当这是真的变异操作中使用,而不是重新绑定一个 。



Answer 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  


文章来源: Global dictionaries don't need keyword global to modify them? [duplicate]