Overload a Python Function



Function overloading means defining multiple functions with the same name but different arguments. This is a built-in feature in many programming languages like C++ or Java. However, in Python, function overloading is not directly supported, but we can achieve it using some techniques.

Python uses a concept called dynamic typing, which allows us to define functions that can take different types and numbers of arguments.

We cannot create multiple functions with the same name, but we can still achieve similar functionality using methods like default arguments, variable-length arguments, or special modules like functools.singledispatch.

Using Default Arguments

One way to overload a function in Python is by using default arguments. We can define a function where some parameters have default values. This lets us call the function with fewer arguments than usual.

If an argument is not provided, the function uses the default value. This makes the function easier to use in different situations.

Example

In the following example, we define a function greet that behaves differently based on whether a name is provided or not ?

# Function with default argument
def greet(name="Guest"):
   print("Hello,", name)

# Call with an argument
greet("Alice")

# Call without an argument
greet()

The output of the above code is ?

Hello, Alice
Hello, Guest

Using Variable-Length Arguments

Another way to overload a function in Python is by using variable-length arguments. Python provides the *args and **kwargs syntax to accept a flexible number of arguments in a function. The *args syntax is used for passing a non-keyworded list of arguments, while **kwargs allows passing keyworded arguments as a dictionary.

This approach helps us create functions that can handle different numbers and types of arguments. We do this by manually checking how many arguments were passed and what types they are, and then writing custom logic based on what was received.

Example

In the example below, we define a function that prints the sum of any number of numbers ?

# Function to sum any number of numbers
def add_numbers(*args):
   return sum(args)

# Call with different numbers of arguments
print(add_numbers(1, 2))
print(add_numbers(3, 4, 5))
print(add_numbers())

The output will be ?

3
12
0

Using Type Checking

Another way of overloading a function is by using type checking. In this approach, we use Python's built-in type() or isinstance() functions inside the function body to check the type of each argument.

Based on the type, we can write different code for different cases. This helps the function respond differently depending on whether it receives a string, a number, a list, or any other type.

Example

In this example, the multiply() function works differently depending on whether we pass numbers or strings ?

# Function that behaves based on type of arguments
def multiply(a, b):
   if isinstance(a, str) and isinstance(b, int):
      return a * b
   elif isinstance(a, int) and isinstance(b, int):
      return a * b
   else:
      return "Unsupported types"

print(multiply(3, 4))     
print(multiply("Hi", 3))  
print(multiply("Hi", "3"))

Following is the output ?

12
HiHiHi
Unsupported types

Using functools.singledispatch Decorator

The Python functools module provides a decorator called singledispatch, which allows us to define a generic function and register multiple versions of it based on the type of the first argument. This is a more structured way to achieve function overloading in Python.

With @singledispatch, you create one main function that works differently based on the type of its first argument ?

  • You start by defining a base version of the function using @singledispatch.
  • Then, you add more versions for different data types using @function_name.register(type).
  • When you call the function, Python looks at the type of the first argument and automatically chooses the matching version.

It is like having one function name but different behaviors depending on the input type.

Example

In this example, we overload the process() function to behave differently for integers, strings, and lists ?

from functools import singledispatch

@singledispatch
def process(arg):
   print("Default processing:", arg)

@process.register(int)
def _(arg):
   print("Processing integer:", arg)

@process.register(str)
def _(arg):
   print("Processing string:", arg)

@process.register(list)
def _(arg):
   print("Processing list of length", len(arg))

# Test with different types
process(10)
process("Hello")
process([1, 2, 3])
process(3.14)  # Falls back to default

We get the following output ?

Processing integer: 10
Processing string: Hello
Processing list of length 3
Default processing: 3.14
Updated on: 2025-04-11T14:32:32+05:30

4K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements