"Least Astonishment" and the Mutable Default Argument
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
The Principle of Least Astonishment (POLA) refers to the idea that a function or behavior should behave in a way that is least surprising to the user. In Python, a classic violation of POLA is using mutable default arguments in functions.
The Issue with Mutable Default Arguments
In Python, default arguments are evaluated once when the function is defined, not every time the function is called. If a mutable object (e.g., a list, dictionary, or set) is used as a default argument, it can persist changes between function calls. This behavior often astonishes developers who expect a fresh object each time.
Example: Unexpected Behavior
Why is this happening?
- The default argument
my_list=[]is evaluated only once when the function is defined. - As a result, the same list is reused across multiple calls to the function.
The Expected Behavior
Most developers would expect the list to be reinitialized (empty) for each call, like this:
The Solution
To avoid this issue, use None as the default argument and initialize the mutable object inside the function.
Corrected Example:
Why Does This Work?
By setting the default value of my_list to None, you ensure that a new list is created inside the function each time it is called. The condition if my_list is None checks if a new list is needed.
General Rule of Thumb
Always avoid using mutable objects (e.g., lists, dictionaries, sets) as default arguments in Python functions.
- Use
Noneinstead. - Initialize the mutable object inside the function body.
Summary
- POLA Violation: Mutable default arguments persist between calls and lead to surprising behavior.
- Solution: Use
Noneas the default and initialize the mutable object inside the function.
This is one of Python's most commonly misunderstood behaviors, but once you know the fix, it becomes a reliable coding pattern. 🚀
Related reading
- Manually raising (throwing) an exception in Python
- Understanding Python super() with __init__() methods
- What is the difference between @staticmethod and @classmethod in Python?
- What is the difference between __str__ and __repr__?
- >, <, >= and <= don''t work with filter in Django
- __init__ got an unexpected keyword argument 'cachedir' when importing top2vec
- __str__ versus __unicode__
- _csv.Error field larger than field limit 131072
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.