@functools.singledispatch in Python
In Python, functools.singledispatch acts as a decorator within the functools module, transforming a function into a generic function. This allows the function to have multiple implementations for the same operation across different types, with the selection of the implementation determined during a call through the dispatch algorithm.\
Single dispatch:
The single dispatch, is a form of generic function dispatch, selects the implementation based on the type of a single argument. Essentially, this decorator introduces function overloading in Python.
To achieve function overloading, you can utilize the register() attribute of the generic function. This attribute, also functioning as a decorator, takes a single parameter specifying the type of data the function will handle.
Syntax
The signature for the singledispatch decorator is as shown below.
@singledispatch
Python @singledispatch Examples:
Example 1:
In this scenario, we are accepting parameters such as a string, an int, and a list. Depending on the type of the parameter, the function will either concatenate or add the values accordingly.
from functools import singledispatch
#Using decorator
@singledispatch
def adding(s):
print("Welcome ",s)
#Using register method to overload function
@adding.register(int)
def _1(s):
print("Computing ",s," + ",s," = ", s+s)
@adding.register(list)
def _2(s):
sum=0
for i in range(0,len(s)+1):
sum=sum+i
print("Sum of all values in the list is ",sum)
adding('Python Programming')
adding(50)
adding([1,2,3,4,5])
Output
Welcome Python Programming
Computing 50 + 50 = 100
Sum of all values in the list is 15
Example 2:
In this situation, we are calculating the multiplication of various primitive data types. However, attempting to access the product function with a string argument will result in a “Not Implemented” response.
from functools import singledispatch
# Function computing multiplication
@singledispatch
def product(num1,num2):
if(type(num1)==type("") or type(num2)==type("")):
return NotImplemented
else:
return num1*num2
#Computing the product of numbers in the list
print("Multiplying 5 * 5 =",product(5,5))
print("Multiplying 5.5 * 5 =",product(5.5,5))
print("Multiplying 1.25 * 2.5 =",product(1.25,2.5))
print("Multiplying 5 * A =",product(5,'A'))
Output
Multiplying 5 * 5 = 25
Multiplying 5.5 * 5 = 27.5
Multiplying 1.25 * 2.5 = 3.125
Multiplying 5 * A = NotImplemented
Example 3:
In this instance, we are negating the values of different types such as int and boolean. However, if the argument is of string or char type, the function will return “Not Implemented.”
from functools import singledispatch
# Function returning negative value of parameter
@singledispatch
def neg(a):
return NotImplemented
@neg.register(int)
def _1(a):
return -a
@neg.register(bool)
def _2(a):
return not a
print("Negative value of 5 is ",neg(5))
print("Negative value of True is ",neg(True))
print("Negative value of A is ",neg('A'))
Output
Negative value of 5 is -5
Negative value of True is False
Negative value of A is NotImplemented
Conclusion:
Therefore, the combination of this decorator and the register() method provides a powerful means to implement function overloading in Python.
References:
Happy Learning 🙂