Python:类变量也会针对新对象进行修改


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()

在运行上面的代码时,为什么exp2对象的值也会被修改?我想把每个对象都分开。无法理解如何做到这一点。

这是因为在构造函数中初始化trialDetails的方式:

def __init__(self, experiment_name, total_trials, trialDetails = TrialDetails()):

您可能认为,在每次调用时,trialDetails都会初始化为TrialDetails类的新实例,但事实并非如此,因为默认参数是绑定到函数定义。因此,您可以为两个HpoExperiment对象获得相同的实例,可以通过将普通print(trialDetails)添加到__init__()来轻松验证。解决方案是将trialDetails的初始化转移到构造函数主体,即:

def __init__(self, experiment_name, total_trials, trialDetails = None):
if not trialDetails:
trialDetails = TrialDetails()
...

在那次更改之后,您得到了两个实例和预期结果:

Experiment Details
exp name =  A
total trials =  5
trial number =  -1
exp name =  B
total trials =  3
trial number =  -1
Update Experiment 1
Experiment Details
exp name =  A
total trials =  5
trial number =  22
exp name =  B
total trials =  3
trial number =  -1

最新更新