Using None as a default argument in Python

avatar

Borislav Hadzhiev

Last updated: Jun 15, 2022

banner

Photo from Unsplash

Using None as a default argument in Python #

None is often used as a default argument value in Python because it allows us to call the function without providing a value for an argument that isn't required on each function invocation. None is especially useful for list and dict arguments.

main.py
def get_employee(name=None, age=None): return {'name': name, 'age': age} # 👇 {'name': None, 'age': None} print(get_employee()) # 👇️ {'name': None, 'age': 30} print(get_employee(age=30)) # 👇️ {'name': 'Alice', 'age': 30} print(get_employee('Alice', 30))

We declared a function with 2 default parameters set to None.

Default parameter values are ones that have the form parameter = expression.

When we declare a function with one or more default parameter values, the corresponding arguments can be omitted when the function is invoked.

Note that positional parameters cannot follow a parameter with a default value because otherwise Python has no way of knowing if we passed an argument for the default parameter or for a positional one.

A None value is often used for default parameters that are not essential to the function.

None is used when the function could still run even if a value for the parameter wasn't provided.

It's a best practice to use None values for non-primitive parameters like lists and dictionaries.

Here is an example how using an empty dictionary as a default value for a parameter can go wrong, and how we can fix it with a None value.

main.py
def get_address(address={}): return address addr1 = get_address() addr2 = get_address() addr1['country'] = 'Germany' print(addr1) # 👉️ {'country': 'Germany'} print(addr2) # 👉️ {'country': 'Germany'}

We called the get_address() function 2 times and stored the results in variables.

Notice that we only set the country key on one of the dictionaries, but both of them got updated.

This is because default parameter values are only evaluated once - when the function is defined.

They are not evaluated each time the function is called.

When a non-primitive default parameter value like a dictionary or list is mutated, it is mutated for all function calls.

To solve this, set the default parameter value to None and conditionally update it in the body of the function.

main.py
def get_address(address=None): if address is None: address = {} return address addr1 = get_address() addr2 = get_address() addr1['country'] = 'Germany' print(addr1) # 👉️ {'country': 'Germany'} print(addr2) # 👉️ {}

The body of the function is run every time it is invoked, so the issue no longer exists.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.