Python循环中创建的对象均具有相同引用问题如何解决?
问题根因
你的代码问题和引用拷贝无关,是Python闭包的迟绑定特性导致的:
- 循环内定义的
lambda: env属于闭包,它不会在定义时立刻捕获env变量的当前值,只会在实际被调用时才去查找env变量的取值 - 等到你在
__main__里遍历调用这些lambda时,for循环已经执行完毕,env变量最终指向的是最后一次迭代(port=3)时生成的Env对象,所有lambda调用时都会读取这个最终的env值,所以输出全是3、对象id也完全相同。
修复方案
最简单的修复方式是给lambda添加默认参数,默认参数会在函数定义阶段完成求值,能当场捕获当前迭代的env值:
把make函数里的
env_fs.append(lambda: env)
修改为
env_fs.append(lambda env=env: env)
修正后的完整代码
import copy class Params: def __init__(self, port): self.__port = port def set_port(self, port): self.__port = port def get_port(self): return self.__port class Env: def __init__(self, params): self.params = params def make(env_class, params, ports): env_fs = [] for port in ports: params_ = copy.deepcopy(params) params_.set_port(port) env = env_class(params_) # 改动点:添加默认参数绑定当前env值 env_fs.append(lambda env=env: env) return env_fs if __name__ == "__main__": fs = make(Env, Params(0), ports=[0, 1, 2, 3]) for f in fs: print(f().params.get_port(), id(f()))
修正后输出示例
0 140352812889616 1 140352812889712 2 140352812889808 3 140352812889904 Process finished with exit code 0
内容的提问来源于stack exchange,提问作者Philipp
相关产品推荐
相关产品推荐

