Python中为对象创建独立函数方法的优雅方案(替代函数复制)
问题:为每个Operator实例创建独立的operation方法
原示例代码如下:
class Operator: def __init__(self, id, operation): self.id = id self.operation = operation def test(self, arg): print(self.operation(arg)) operators = [] for i in range(4): op = lambda x: x+i operators.append(Operator(i, op)) operators[0].test(5) operators[1].test(5) operators[2].test(5) operators[3].test(5)
直观预期输出应为5、6、7、8,但实际输出全为8。核心原因是:lambda中的i是自由变量,它不会在lambda定义时绑定当前循环的i值,而是在lambda被调用时才去查找i的当前值。循环结束后i的最终值是3,所以所有lambda执行时都会使用i=3,计算结果都是5+3=8。
更简洁的实现方式
方式1:给lambda添加默认参数绑定当前值
通过默认参数的特性,让lambda在定义时就绑定当前循环的i值:
operators = [] for i in range(4): op = lambda x, i=i: x+i # 默认参数i在定义时即绑定当前循环的i值 operators.append(Operator(i, op))
每个lambda会拥有独立的i参数副本,调用时不会互相干扰。
方式2:使用functools.partial固定参数
借助functools.partial将i参数预先绑定到函数中:
from functools import partial def add_i(x, i): return x + i operators = [] for i in range(4): op = partial(add_i, i=i) # 固定i参数,生成仅需传入x的新函数 operators.append(Operator(i, op))
partial会创建新的函数对象,每个对象都绑定了当前循环的i值,实现独立的逻辑。
方式3:利用嵌套函数的作用域绑定
通过嵌套函数创建局部作用域,确保每个lambda引用的i是当前循环的独立值:
operators = [] for i in range(4): def create_op(current_i): return lambda x: x + current_i op = create_op(i) operators.append(Operator(i, op))
每次调用create_op时,current_i会被赋值为当前循环的i,返回的lambda会引用这个局部作用域中的值,避免了共享外部变量的问题。
内容的提问来源于stack exchange,提问作者Anne Aunyme
相关产品推荐
相关产品推荐

