Python offers us to specify that a function argument is optional by providing a default value to it. While this is widely used and one of the major features of the language, it can lead to confusions when enough thought is not given to the implementation details of the feature. Especially when the default value is a mutable.
Example of a function implementation with optional argument with default value as a mutable.
>>> def example(numbers=): ... numbers.append(1) ... return numbers ... >>>
Simply put, a mutable object can be changed after it is created, and an immutable object can’t. In python list, dictionaries are mutable objects while integers, strings, tuple, etc are immutable objects.
A common misconception is that the optional argument will be set to the default value provided each time the function when called without supplying the value for the optional argument. Let us see.
>>> example()  >>> example() [1, 1] >>> example() [1, 1, 1] >>> example() [1, 1, 1, 1] >>> example() [1, 1, 1, 1, 1] >>>
We would generally assume that each time example() is called without the optional argument, numbers would be assigned to and empty list. Inside the function, 1 would be appended to the list and returned. Well, our hypothesis is false in this case.
This is because, the default value for a function is only evaluated once which is during the function definition. This implies that the default value for the optional parameter numbers is initialized to the default value, an empty list at the time of the function definition. Any further calls of the function example would then utilize the same list everytime it is called therefore the behavior we saw in the examples above.