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

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

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

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值