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

Python类实例属性共享问题及深拷贝解决方案咨询

问题解答

是的,使用copy.deepcopy(so.common_params)绝对是可行的解决方案,而且是处理这类问题的标准方式之一。

为什么原来的代码会出问题?

你遇到的问题本质是Python中可变对象的引用传递特性:

  • 模块SimulatorObjects里的common_params是一个字典(可变对象),当你在__init__里写self.common_params = so.common_params时,并没有创建新的字典,只是让当前实例的common_params属性指向了模块中那个字典的内存地址。
  • 所以当你修改ss.common_params['number_agents'] = 10时,实际修改的是模块里的原始字典,后续新建的new_ss实例依然指向这个被修改过的字典,自然读不到默认值1。

为什么copy.deepcopy()能解决问题?

copy.deepcopy()会递归地复制原字典中的所有元素:

  • 它会创建一个全新的字典对象,包括字典里嵌套的可变元素(比如你的other_stuff列表),每个实例的common_params都是完全独立的副本。
  • 这样修改任何一个实例的common_params,都不会影响其他实例或者模块里的原始字典,新创建的实例自然会拿到初始的默认值。

补充说明

如果你的common_params字典里只有不可变类型(比如整数、字符串、浮点数),用浅拷贝(比如so.common_params.copy()或者copy.copy(so.common_params))也能解决问题。但因为你的字典里包含other_stuff这个列表(可变对象),浅拷贝只会复制列表的引用,修改列表元素还是会影响其他实例,所以必须用deepcopy才能彻底隔离所有可变元素。

举个验证的例子:

import copy
import SimulatorObjects as so

class SalesSimulator(object):
    def __init__(self):
        self.common_params = copy.deepcopy(so.common_params)

# 测试
ss = SalesSimulator()
print(ss.common_params['number_agents'])  # 输出1
ss.common_params['number_agents'] = 10
print(ss.common_params['number_agents'])  # 输出10

new_ss = SalesSimulator()
print(new_ss.common_params['number_agents'])  # 输出1,符合预期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 13:28:15