首页 > 解决方案 > 后面的代码行似乎会影响前面行的执行方式。这是怎么回事?

问题描述

下面的代码块按预期工作

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)

但是当我将以下内容添加到更新末尾时

    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)

标签: python

解决方案


线

patient.log.append(entry)

entry将字典附加到patient.log,它不会将entry字典的元素“添加”到列表中。所以当你在下一行打电话时

entry["patient_id"] = patient.id

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

解决此问题的一种方法是创建copy字典,而不是参考,另请参阅此帖子

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

正如该帖子还提到的那样,请确保您了解其copy工作原理,因为它可能并不总是按预期工作。特别是如果您复制的对象中有引用。


推荐阅读