后面的代码行似乎会影响前面几行的执行方式。这是怎么回事?



下面的代码块按预期工作

patient = Patient()
patient.log = []
patient.id = "xyz"
patient.example_attribute = []
ALL_PATIENT_LOG = []
def update(patient, attribute, argument, replace = False):
now = datetime.now()
entry = {"argument": argument, "attribute": attribute, "time": now.strftime("%H:%M on %d/%m/%y")}
patient.log.append(entry)

但是当我在update

末尾添加以下内容时
entry["patient_id"] = patient.id #  we also need to include the patient's ID for the global log
ALL_PATIENT_LOG.append(entry)
if replace:
patient.__dict__[attribute] = [argument]
else:    
patient.__dict__[attribute].append(argument) 

更改了patient.log条目,使其也包含患者id

这违背了我对python工作原理的理解,因为我认为后面的行不能影响前面的行的执行。我误解了什么,使我无法理解为什么它是这样执行的?我怎样才能改变这段代码来获得想要的行为呢?(两个不同的日志条目取决于它是被附加到患者日志还是ALL_PATIENT_LOG)

patient.log.append(entry)

entry字典追加到patient.log,它不"将entry字典中的元素添加到列表中。所以当你在下一行调用

entry["patient_id"] = patient.id

您正在更改entry字典,并且由于patient.log引用该字典,因此当您查找该列表时,它将具有更新的信息。

解决这个问题的一个方法,是创建一个copy的字典,而不是一个参考,也见这篇文章:

patient.log.append(entry.copy())

正如那篇文章也提到的,确保你了解copy是如何工作的,因为它可能并不总是像预期的那样工作。尤其是当你复制的对象中有引用的时候。

最新更新