-1

The below block of code works as intended

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)

But when I add the following to the end of 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) 

the patient.log entry is changed such that it also contains the patient id

This violates my understanding of how python works, as I thought that later lines cannot affect how earlier lines are executed. What have I misunderstood which prevents me from understanding why this executes the way it does? How could I change this code to get the desired behaviour? (two different log entries depending on whether its being appended to the patient log or the ALL_PATIENT_LOG)

John Salter
  • 182
  • 10
  • 2
    lists don't contain copies of objects, but references to them – Sayse Oct 18 '21 at 09:14
  • 1
    Note that you are asking two questions here. Both "what is wrong", and "how do I change this to get what I intended". The first is easy to answer, the second can have multiple answers, and depends based on prefferences and application. – Karl Oct 18 '21 at 09:28

1 Answers1

1

The line

patient.log.append(entry)

Appends the entry dictionary to the patient.log, it does not "add" the elements of the entry dictionary to the list. So when you in the next line call

entry["patient_id"] = patient.id

You are changing the entry dictionary, and since the patient.log is referencing to that dictionary, it will have the updated information when you look up that list.

A way to solve this, is to create a copy of the dictionary, instead of a reference, also see this post :

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

As that post also mentions, make sure you understand how copy works, as it might not always work as intended. Especially if there are references within the object you copy.

Karl
  • 1,074
  • 8
  • 25