You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何持有adder函数的变量b未每次调用都输出4?请求解惑

为什么闭包调用多次输出不是始终为4?

嘿,这个问题问到点子上了!很多刚接触闭包的开发者都会掉进这个误区,我来给你讲明白~

首先咱们先还原一下你大概率遇到的代码场景(毕竟没贴代码,但这个坑太常见了):

def create_adder():
    x = 3
    def adder(y):
        nonlocal x  # 要是在JS里就是直接修改x,不用写这个声明
        x += y
        return x
    return adder

b = create_adder()
print(b(1))  # 第一次输出4
print(b(1))  # 第二次居然输出5,不是4?!

核心原因:闭包抓的是「作用域引用」,不是「变量固定值」

你以为b(也就是adder函数)记住的是x=3这个固定值?错啦!它记住的是整个包含x的作用域的引用。也就是说,adder里用的x,和create_adder函数里的x是同一个变量,只是通过闭包“拎”出来用了。

  • 第一次调用b(1)时,x += 1把原作用域里的x从3改成了4,然后返回4;
  • 第二次调用时,这个x已经是4了,再加1自然就变成5了——因为作用域里的x已经被修改过,闭包会一直用这个更新后的变量。

那怎么让每次调用都输出4?

如果想让每次调用都得到4,你得让闭包只读取x的值,而不修改它。比如把代码改成这样:

def create_adder():
    x = 3
    def adder(y):
        return x + y  # 只读取x的值,不修改它
    return adder

b = create_adder()
print(b(1))  # 4
print(b(1))  # 还是4!

这时候x在作用域里从来没被修改过,始终是3,所以每次加1都是4。

说白了,关键就看你在闭包里有没有修改捕获的变量——如果只是读,那值就一直是最初的;如果改了,那修改会存在作用域里,后续调用就用新值啦。

内容的提问来源于stack exchange,提问作者pragun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:59:02