Python 闭包:为什么允许在闭包中更改字典,而不允许更改数字?

Python closure: Why changing dictionary in closure is allowed while changing numbers isn't?

当我尝试在闭包中更改字典时,此代码运行良好

def a():
    x = {'a':'b'}
    def b():
        x['a'] = 'd'
        print(x)
    return b
>>> b = a()
>>> b()
{'a':'d'}

输出符合我的预期。但为什么下面的代码不起作用?

def m():
x = 1
def n():
    x += 1
    print(x)
return n
>>> n = m()
>>> n()

UnboundLocalError: 赋值前引用了局部变量'x'

老实说,我知道我们可以使用 nonlocal x 语句来解决这个问题
但是有人可以为我更深入地解释原因吗? 字典和数字有什么区别
谢谢!

Python 在这方面有很好的 FAQ

简而言之,当您修改字典或任何 mutable 对象时,您修改的是同一个对象,因此您不会 re-assign 变量。如果是整数,由于它是不可变的,通过执行 += 你可以创建一个新对象并将其放入 x。由于 x 现在是在内部函数内部定义的,但您试图从外部函数中获取数据,所以您遇到了问题。

您可以使用 id() 检查它是否是同一个对象。