3 More Python Functools Tips
The Functools module is essential for writing clean, readable, and reusable code in Python. You can read another article called 3 Python Functools Tips if you want to learn about enhancing performance.
In this article, you are going to learn about three more Python Functools tips, which are predefined functions, single dispatch, and total ordering.
Partial or Predefined Functions
Predefined functions mean creating a version of a function by assigning values to its arguments.
from functools import partial
def add(a, b):
print(a + b)
# order of the arguments maters
add2and5 = partial(add, 2, 5) # 2 for a, 5 for b
add2and1 = partial(add, 2, 1) # 2 for a, 1 for b
add2and2()
add2and1()
In this example, theadd
function takes two arguments, a
and,b
and returns the addition of a
andb
. By using partial
function from functools
we defined add2and2
, add2and1
function which have predefined a
and b
values.
The first argument of partial
is the function that we want to use for predefinition. Other arguments are the value of the arguments of the function.
Singledispatch | Generics
singledispatch
is a decorator that is used for creating versions of a function for different types of data types. This function can behave differently for different data types.
More about decorators:
In order to use singledispatch
with a function, we must write versions in which the behavior of the function will change and a version for general usage.
from functools import singledispatch
@singledispatch
def append(obj, x):
print("Unsupported type")
@append.register
def _(obj: list, x: list):
return obj + x
@append.register
def _(obj: set, x: set):
return obj.union(x)
@append.register
def _(obj: str, x: str):
return obj + x
print(append([1, 2, 3], [4, 5]))
print(append({1, 2, 3}, {4, 5}))
print(append("1 2 3", " 4 5"), "\n")
If the type is not supported, the original function is called
append(2, 3)
In this example, the function with singledispatch
decorator is the version that we want to run for undefined data types.
Other versions with append.register
decorator are versions for specified data types. As you noticed, the decorator starts with the function name that we are working with (append in this case). Also, other functions are named_
.
Use type annotations for specifying types.
Total Ordering
total_ordering
is used for automatically defining __lt__()
, __le__()
, __gt__()
, __ge__()
based on,__eg__()
and on of the four methods of a class. These methods are less than, less or equal, greater than, greater or equal, and equal methods (<, <=, >, >=).
from functools import total_ordering
@total_ordering
class Circle:
def __init__(self, radius):
self.radius = radius
def __eq__(self, other):
return self.radius == other.radius
def __lt__(self, other):
return self.radius < other.radius
studentA = Circle(10)
studentB = Circle(12)
# all compressions are working even if we don't define all four
print(studentA == studentB)
print(studentA != studentB)
print(studentA < studentB)
print(studentA <= studentB)
print(studentA > studentB)
print(studentA >= studentB)
In this example, theCircle
class has only __eq__
and __lt__
methods but each operation works fine thanks tototal_ordering
.
Write less, do more.