Python: Typing a function with default parameters

Updated: February 17, 2024 By: Guest Contributor Post a comment

Overview

Python’s dynamic nature makes it flexible and easy to write code. However, with the introduction of type hints in PEP 484, Python developers now have the option to make their codebases more readable and self-documenting, while at the same time catching potential bugs before runtime. This tutorial delves into the specifics of typing functions with default parameters, guiding you through from the very basics to more advanced concepts, complete with examples and their outputs.

Introduction to Function Typing

Before diving into typing functions with default parameters, it’s important to grasp the basics of function typing. Typing in Python allows you to explicitly declare the data type of a function’s arguments and return value. This is achieved using Python’s typing module. Here’s a simple example:

from typing import List
def greet(names: List[str]) -> None:
    for name in names:
        print(f"Hello, {name}!")

Here, greet is expected to receive a list of strings as an argument, and it doesn’t return anything (hence None).

Typing Functions with Default Parameters

When a function has parameters with default values, the typing remains nearly the same. However, it’s essential to ensure that the default value matches the declared type. Here’s a straightforward example:

def repeat(message: str, times: int = 1) -> None:
    for _ in range(times):
        print(message)

In the above function, message is a string, and times is an integer with a default value of 1. The function prints the message a specified times number of times.

Advanced Typing Scenarios

Let’s step up the complexity a bit. Suppose you have a function that could accept null values as a default parameter. In Python, you would use the Optional type from the typing module to handle such cases.

from typing import Optional
def log(message: Optional[str] = None) -> None:
    if message is not None:
        print(message)
    else:
        print("No message provided.")

This function accepts a message that could either be a string or None, the default value.

Combining Types with Default Parameters

Python’s flexibility allows for combinations of types with default parameters, utilizing the Union type for arguments that can accept multiple types. Here’s how you can handle it:

from typing import Union
def display(info: Union[str, int] = "Hello!") -> None:
    print(f"Info: {info}")

In this example, the parameter info can be either a string or an integer, with a default string value of “Hello!”.

Using **kwargs and *args with Types and Defaults

Functions that accept a variable number of arguments (*args) or keyword arguments (**kwargs) can also be typed, even though they don’t have default values in the conventional sense. Here’s how this could look:

from typing import Any, Callable
def complex_function(*args: int, callback: Callable[[int], Any] = None) -> None:
    result = sum(args)
    if callback:
        callback(result)
    else:
        print(result)

Here, *args must be integers, and callback is an optional parameter that expects a function.

Conclusion

Typing functions with default parameters in Python enhances code readability and helps prevent runtime errors by catching potential type mismatches during development. As you’ve seen, creating clear, typed interfaces for your functions is straightforward and beneficial, even when default parameters or more complex scenarios are involved.