在“闭包”中,将外部函数赋值给一个变量后,局部变量“变为”全局变量的问题

这个问题来源于以下的关于“闭包”的例子,先猜一猜运行结果是什么

def funX():
    x = 5
    def funY():
        nonlocal x
        x += 1
        return x

a = funX()
print(a())
print(a())
print(a())

结果是:

6
7
8

你可能会疑惑,这局部变量 x 怎么跟全局变量一样了? x 不是应该在每次调用的时候都重新初始化为5了吗?

其实大家仔细看看就明白了,当 a = funX() 的时候,只要 a 变量没有被重新赋值,funX() 就没有被释放,也就是说局部变量 x 就没有被重新初始

为了方便理解,我们在外部函数中再加一条代码:print(x)

def funX():
    x = 5
    print(x)
    def funY():
        nonlocal x
        x += 1
        return x
    return funY

a = funX()
print(a())
print(a())
print(a())

我们再运行一下,局部变量x“变为”全局变量的原因就出现了

5
6
7
8

如果还不明白,我们再修改一下代码,会发现:

“5”是在将funX()赋值给变量a的过程中产生的
我们缩短一下句子:
“5”是在赋值过程中产生的

也就是说系统在执行 a = funX() 时调用了 funX() 函数,执行了 print(x) 指令,并且返回了值 funY ,此时 a 的值便是 funY,而内部函数funY()又暗含了条件x=5

倘若视funY()为独立函数,那么调用三次a()的过程相当于在执行以下指令:

>>>x = 5
>>>def funY():
        global x
        x += 1
        return x
    return funY

>>>funY()
6
>>>funY()
7
>>>funY()
8

因此,问题的关键在于a = funX() 是一个赋值的过程,只要 a 变量没有被重新赋值,funX() 就没有被释放,局部变量 x 就没有被初始化为5

猜你喜欢

转载自blog.csdn.net/A_No2Tang/article/details/113785130