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

为何修改HpoExperiment实例exp1时exp2也被改动?如何隔离?

Python类实例状态共享问题的原因与解决方法

问题描述

运行以下Python代码时,修改HpoExperiment类的实例exp1的trial_number后,实例exp2的该属性值也随之改变。需要让每个实例的状态相互独立,请问问题原因是什么?如何实现状态隔离?

class TrialDetails:
    trial_number: int
    def __init__(self, trial_number=-1):
        self.trial_number = trial_number
    def set_trial_number(self, trial_number):
        self.trial_number = trial_number
class HpoExperiment:
    experiment_name: str
    total_trials: int
    trialDetails: object
    def __init__(self, experiment_name, total_trials, trialDetails = TrialDetails()):
        self.experiment_name = experiment_name
        self.total_trials = total_trials
        self.trialDetails = trialDetails
    def set_trial(self, trial_number):
        self.trialDetails.set_trial_number(trial_number)
    def display(self):
        print ("exp name = ", self.experiment_name)
        print ("total trials = ", self.total_trials)
        print ("trial number = ", self.trialDetails.trial_number)

def main():
    exp1 = HpoExperiment("A", 5)
    exp2 = HpoExperiment("B", 3)
    print("Experiment Details")
    exp1.display()
    exp2.display()
    print("Update Experiment 1")
    exp1.set_trial(22)
    print("Experiment Details")
    exp1.display()
    exp2.display()

if __name__ == '__main__':
    main()

问题原因

这是Python中可变默认参数的常见陷阱:

  • 函数的默认参数是在函数定义阶段创建的,而非每次调用函数时重新生成
  • HpoExperiment.__init__方法里的trialDetails = TrialDetails(),会在类定义时生成一个TrialDetails实例,所有没有显式传入trialDetails参数的HpoExperiment实例,都会共享这同一个TrialDetails对象
  • 修改exp1的trial_number时,实际是修改了这个共享对象的属性,exp2引用的是同一个对象,自然属性值也会跟着变化

实现实例状态隔离的方法

方法1:修改默认参数为None,在初始化时创建新实例

把__init__的默认参数改为None,然后在方法内部判断,若没有传入自定义的trialDetails,就新建一个独立的TrialDetails实例:

class HpoExperiment:
    experiment_name: str
    total_trials: int
    trialDetails: object
    def __init__(self, experiment_name, total_trials, trialDetails=None):
        self.experiment_name = experiment_name
        self.total_trials = total_trials
        # 为每个实例创建独立的TrialDetails对象
        self.trialDetails = trialDetails if trialDetails is not None else TrialDetails()
    def set_trial(self, trial_number):
        self.trialDetails.set_trial_number(trial_number)
    def display(self):
        print ("exp name = ", self.experiment_name)
        print ("total trials = ", self.total_trials)
        print ("trial number = ", self.trialDetails.trial_number)

方法2:显式传入独立的TrialDetails实例

在创建HpoExperiment实例时,手动为每个实例传入新的TrialDetails对象,确保每个实例拥有专属的状态:

def main():
    # 每个实例都传入独立的TrialDetails对象
    exp1 = HpoExperiment("A", 5, TrialDetails())
    exp2 = HpoExperiment("B", 3, TrialDetails())
    print("Experiment Details")
    exp1.display()
    exp2.display()
    print("Update Experiment 1")
    exp1.set_trial(22)
    print("Experiment Details")
    exp1.display()
    exp2.display()

内容的提问来源于stack exchange,提问作者Saad Khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 23:05:24