Python在lambda内绑定另一个lambda的方法 解决递归调用报错
问题原因
Python 闭包的变量采用迟绑定机制:函数(包括lambda匿名函数)内部引用的外部变量,只会在函数实际执行时才会查找变量的当前值,而不是在函数定义阶段就绑定变量当时指向的值。你遇到的递归问题和lambda本身无关,就算用def定义普通函数也会出现相同情况:新函数引用的my_filter在实际调用时已经被覆盖为新创建的函数本身,触发无限递归。
最优解决方案
最简洁且性能开销可忽略的方案是利用函数默认参数的特性:默认参数会在函数定义阶段完成求值并绑定,所以你可以把当前的旧过滤器作为默认参数传入新lambda,直接固定旧实例的引用:
filter_even = True my_filter = lambda x: x # 基础过滤器 if filter_even: # prev_filter默认参数在定义阶段就绑定当前的my_filter值 my_filter = lambda x, prev_filter=my_filter: prev_filter(x) and x % 2 == 0 print(list(filter(my_filter, [1,2,3,4]))) # 输出结果:[2, 4]
适合多规则拼接的可选方案
如果需要动态拼接多个过滤规则,建议封装高阶函数统一处理绑定逻辑,代码可读性更强:
def add_filter(old_filter, condition): return lambda x: old_filter(x) and condition(x) my_filter = lambda x: x # 可多次链式拼接规则 filter_even = True if filter_even: my_filter = add_filter(my_filter, lambda x: x%2 == 0) filter_greater_than_2 = True if filter_greater_than_2: my_filter = add_filter(my_filter, lambda x: x>2) print(list(filter(my_filter, [1,2,3,4]))) # 输出结果:[3,4]
内容的提问来源于stack exchange,提问作者allo
相关产品推荐
相关产品推荐

