Default mutable arguments
def x(y=[]):
return y
print(x())
# >> []
x().append(10)
print(x())
# >> [10]
In this part:
- We define a function x with a default argument y=[].
- When we first call x(), it returns an empty list [].
- We then append 10 to the result of x().
- When we call x() again, it surprisingly returns
10.
This behavior occurs because:
- In Python, default arguments are evaluated only once, when the function is defined.
- The empty list [] is created once and reused for all subsequent calls to x().
- Modifying this list affects all future calls to the function.
def my_function(default_list = None):
if default_list == None:
default_list = []
return default_list
print(my_function())
# >> []
my_function().append(8)
print(my_function())
# >> []
This part demonstrates the recommended way to handle mutable default arguments:
- We define my_function with default_list = None.
- Inside the function, we check if default_list is None, and if so, we create a new empty list.
- When we call my_function(), it returns a new empty list each time.
- Appending to the result of my_function() doesn’t affect future calls.
This approach ensures that each call to my_function() gets a fresh, empty list, avoiding the issues seen in the first part.
my_function().append(8)
my_function().append(8)
print(my_function())
# >> []
Step-by-step explanation
my_function().append(8)
- This line calls my_function(), which returns a new, empty list.
- The append(8) method is then called on this new list, adding the integer 8 to it.
- However, this modified list is not stored anywhere. It’s created, modified, and then immediately discarded because there’s no variable assigned to hold it.
print(my_function()) - This line calls my_function() again.
- Because of how my_function() is defined, it creates and returns a new, empty list every time it’s called.
- This new list is completely separate from the one created and modified in the previous line.
# >> []
Step-by-step explanation
- This is the output of the print statement.
- It shows an empty list, confirming that my_function() indeed returned a fresh, empty list.
Key points
- Each call to my_function() creates a new list object.
- Modifications to one list returned by my_function() do not affect subsequent calls.
- This behavior is different from the first example with function x(), where modifications persisted between calls.
Why this behavior is correct
This behavior demonstrates the proper handling of mutable default arguments.By using None as the default argument and creating a new list inside the function when needed, we ensure that:
- Each call to the function gets its own fresh list.
- There’s no shared state between different calls to the function.
- Modifications to the returned list in one call don’t affect the lists returned by future calls.
This pattern avoids the common pitfall associated with mutable default arguments and provides more predictable and safer behavior in Python functions.
Tags:
Python, Funtion Default Arguments