为什么在这种情况下不需要使用全局关键字?

20
cache = {}
def func():
    cache['foo'] = 'bar'
print cache['foo'] 

输出

bar

为什么这段代码可以运行而且不需要使用global关键字呢?


6
可变对象不需要使用 global - Ashwini Chaudhary
@AshwiniChaudhary 能否添加一个参考文献? - akhan
@samsamara 这不是我的意思,使用mylist = ['a']会显式地定义一个新的局部变量。请执行一次变异,例如 mylist.append(10) 等。 - Ashwini Chaudhary
是的,如果您进行这样的变异,它将按预期工作,因为您只是在访问它。但是,假设我更改我的函数以接受列表作为参数,def f1(mylist): mylist = mylist + ['a'];在这里,我使用赋值运算符突变了列表。我有mylist = ['s']并调用f1(mylist)。现在,由于列表是可变的,并且您将列表对象传递给f1(),但它仍然没有突变mylist - samsamara
@samsamara mylist = mylist + ['a'] 不是一种变异,它会创建一个全新的列表。 - Ashwini Chaudhary
显示剩余2条评论
1个回答

25
因为您没有将值赋给“cache”,而是直接更改了字典本身。 "cache" 仍然指向该字典,因此它本身未更改。 行 "cache ['foo'] ='bar'" 等同于 "cache.__setitem__ ('foo','bar')"。 换句话说, "cache" 的值是一个 Python 字典,并且该值本身是可变的。
如果您尝试使用 "cache ='bar'" 来更改 "cache" 所引用的内容,则需要使用 "global" 关键字来更改 "cache" 所引用的内容。
也许我之前回答类似问题的答案可以帮助您理解区别: Python list doesn't reflect variable change

2
这样做是否可以违背使用 global 关键字的初衷? - Bunny Rabbit
2
@BunnyRabbit:使用global关键字的目的是让Python编译器知道要更改哪个结构。要完全理解为什么需要这样做,需要深入了解Python的内部工作方式(locals()globals()、字节码等)。这里没有违反任何规定,动态语言并不是要阻止您修改全局变量的。 :-) - Martijn Pieters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接