Python Functools Module
The functools module is for higher-order functions: functions that act on or return other functions. In general, any callable object can be treated as a function for the purposes of this module.
Importing the Module
import functools
Caching (lru_cache)
Decorator to wrap a function with a memoizing callable that saves up to the maxsize most recent calls. It can save time when an expensive or I/O bound function is periodically called with the same arguments.
import functools
@functools.lru_cache(maxsize=128)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(30))
print(fibonacci.cache_info())
Partial Functions (partial)
Return a new partial object which when called will behave like the original function called with the positional arguments args and keyword arguments keywords.
import functools
def power(base, exponent):
return base ** exponent
# Create a new function that squares a number
square = functools.partial(power, exponent=2)
print(square(5)) # Output: 25
Reduce (reduce)
Apply a function of two arguments cumulatively to the items of a sequence, from left to right, so as to reduce the sequence to a single value.
import functools
# Calculate the product of a list
items = [1, 2, 3, 4, 5]
product = functools.reduce(lambda x, y: x * y, items)
print(product) # Output: 120 (1*2*3*4*5)
Decorator Metadata (wraps)
This is a convenience function for invoking update_wrapper() as a function decorator when defining a wrapper function. It copies the docstring, name, and other metadata from the wrapped function to the wrapper.
import functools
def my_decorator(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
print('Calling decorated function')
return f(*args, **kwargs)
return wrapper
@my_decorator
def example():
"""Docstring"""
print('Called example function')
print(example.__name__) # Output: example (without @wraps it would be 'wrapper')
print(example.__doc__) # Output: Docstring
Total Ordering (total_ordering)
Given a class defining one or more rich comparison ordering methods, this class decorator supplies the rest.
import functools
@functools.total_ordering
class Student:
def __init__(self, grade):
self.grade = grade
def __eq__(self, other):
return self.grade == other.grade
def __lt__(self, other):
return self.grade < other.grade
s1 = Student(90)
s2 = Student(80)
print(s1 > s2) # True (automatically generated from __lt__)