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

如何在Python闭包中捕获值而非引用,解决循环内变量捕获异常?

如何在Python闭包中捕获值(而非引用)?

问题原因

Python的闭包采用延迟绑定规则:闭包内部引用的变量,会在函数实际被调用时才进行取值,而非闭包定义时就固定下来。
你给出的示例中,所有echo函数都引用了同一个循环变量str,循环结束后str的值已经被更新为列表最后一个元素zebra,所以所有函数调用时的返回值都为zebra。

注意:示例中使用了list、str作为变量名,这两个名称属于Python内置类型标识,不建议用作自定义变量,避免覆盖内置功能。

解决方案

下面是三种常用的实现方式,都可以达到预期输出:

方法1:利用函数默认参数的提前求值特性

Python函数的默认参数会在函数定义阶段完成求值,我们可以借助这个特性绑定当前循环的变量值:

def makeListOfFuncs(strings):
    func_list = []
    for s in strings:
        # 把当前循环的s赋值给默认参数current_str,定义阶段就固定值
        def echo(current_str=s):
            return current_str
        func_list.append(echo)
    return func_list

方法2:使用functools.partial提前绑定参数

functools.partial可以为目标函数提前绑定参数,生成一个新的可调用对象,参数值在绑定阶段就会固定:

from functools import partial

def makeListOfFuncs(strings):
    func_list = []
    for s in strings:
        def echo(current_str):
            return current_str
        # 把当前s绑定为echo的入参
        func_list.append(partial(echo, s))
    return func_list

方法3:用立即执行的lambda创建临时作用域

通过外层lambda立刻执行传入当前循环值,生成临时作用域存储当前值,内层闭包捕获临时作用域的变量:

def makeListOfFuncs(strings):
    func_list = []
    for s in strings:
        # 外层lambda接收s为参数并立刻调用,内层lambda捕获固定的x值
        func_list.append((lambda x: lambda: x)(s))
    return func_list

以上三种方法执行测试代码后,都会输出你预期的结果:

bird
fish
zebra

内容的提问来源于stack exchange,提问作者Sean B. Durkin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 02:15:04