This is probably a python “feature” that every junior developer has bumped into – once you make an empty list as a default argument in Python, it works as expected only for the first object of the class. For the second object – not exactly. Don’t worry, everyone has hit that bug, even it they are not willing to admit it.
The bug actually looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
class Task: def __init__(self, title, description, urgency): self.title = title self.description = description self.urgency = urgency def complete_task(task, grouped_tasks = []): task.status = "completed" grouped_tasks.append(task.title) return grouped_tasks task1 = Task("Homework", "Physics and Math", 5) work = complete_task(task1) task2 = Task("Fun", "Civilization 5 ", 15) fun = complete_task(task2) task3 = Task("Sports", "Football", 3) sports = complete_task(task3) print("Homework", work) print("Fun", fun) print("Sports", sports) |
And the result is this one:
1 2 3 |
Homework ['Homework', 'Fun', 'Sports'] Fun ['Homework', 'Fun', 'Sports'] Sports ['Homework', 'Fun', 'Sports'] |
However, the correct way to do it is with this function with the “grouped_tasks is None” check:
1 2 3 4 5 6 |
def complete_task(task, grouped_tasks = None): task.status = "completed" if grouped_tasks is None: grouped_tasks = [] grouped_tasks.append(task.title) return grouped_tasks |
And the result looks like this:
1 2 3 |
Homework ['Homework'] Fun ['Fun'] Sports ['Sports'] |
The reason why? Well, I explained it in the YouTube video below, but just to underline it once more:
Python evaluates the function when it’s defined. The evaluation has a side effect: any mutable default arguments (lists, dictionaries, etc) are created during evaluation and become part of the function. In our example, a list object is created when the function is evaluated. Now that specific list object is used as the grouped_tasks argument whenever the function is called without a grouped_tasks argument being provided, as the code in the next listing shows.
Thanks and enjoy it!