Skip to main content

Precautions with Default Arguments in Python

··2 mins·
Python
Makoto Morinaga
Author
Makoto Morinaga
A personal notebook for tech notes, coding, and system experiments.
Table of Contents

In Python, functions (or methods) can define default values for arguments. When an argument is omitted during function invocation, the specified default value is used.

sample.py
def foo(text='Good morning'):
    print(text)

foo()
# Good morning
foo(text='Hello')
# Hello

In the example above, the function assigns Good morning as the default value to text. If an argument is omitted, the default value is used; otherwise, the explicitly provided value takes precedence.

Setting default parameters can be useful in many cases, but there are important considerations to keep in mind.

Important Consideration When Using Default Arguments
#

Although default arguments are convenient, a significant pitfall exists: mutable objects such as lists or dictionaries should not be used as default arguments.

This is because default argument values in Python are evaluated only once at function definition, not upon each function call. Consequently, mutable objects specified as default arguments persist across multiple function calls, leading to unintended modifications.

Example of Unexpected Behavior with Mutable Default Arguments
#

Consider the following function, which uses a list as a default argument:

sample.py
def foo(text_list=[], text='Good morning'):
    text_list.append(text)
    print(text_list)

foo()
# ['Good morning']
foo()
# ['Good morning', 'Good morning']
foo()
# ['Good morning', 'Good morning', 'Good morning']
foo(text_list=[])
# ['Good morning']
foo()
# ['Good morning', 'Good morning', 'Good morning', 'Good morning']

Since the list text_list is shared across multiple function calls, elements accumulate in an unintended manner.

Recommended Approach #

To avoid this issue, None should be used as the default argument, and the list should be initialized within the function.

sample.py
def foo(text_list=None, text='Good morning'):
    text_list = text_list or []  # Initialize as an empty list if None
    text_list.append(text)
    print(text_list)

foo()
# ['Good morning']
foo()
# ['Good morning']
foo()
# ['Good morning']
foo(text_list=[])
# ['Good morning']
foo()
# ['Good morning']

By implementing this approach, a new list is properly initialized for each function invocation, preventing undesired side effects.

Related

Basics of Bitwise Enumeration
··2 mins
Algorithm Python
Summary of Underscore Usage in Python
··5 mins
Python