Functools Module: Higher-Order Functions and Functional Programming
TL;DR
The functools module provides utilities for functional programming including partial(), lru_cache(), singledispatch(), and reduce() for creating reusable, optimized higher-order functions.
Interesting!
The @lru_cache decorator can dramatically speed up recursive functions like Fibonacci calculations by memoizing results - turning an O(2^n) algorithm into O(n) with just one line!
Function Caching
python code snippet start
from functools import lru_cache
@lru_cache(maxsize=128)
def expensive_function(n):
print(f"Computing for {n}")
return n * n * n
# First call - computation happens
result1 = expensive_function(5) # Prints: Computing for 5
# Second call - cached result returned
result2 = expensive_function(5) # No print - cached!
@lru_cache(maxsize=None)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
python code snippet end
Partial Functions
python code snippet start
from functools import partial
def multiply(x, y, z):
return x * y * z
# Create specialized function
double_triple = partial(multiply, 2, 3)
result = double_triple(4) # Same as multiply(2, 3, 4) = 24
def greet(greeting, name, punctuation="!"):
return f"{greeting}, {name}{punctuation}"
say_hello = partial(greet, "Hello")
print(say_hello("Alice")) # Hello, Alice!
python code snippet end
Single Dispatch
python code snippet start
from functools import singledispatch
@singledispatch
def process_data(data):
return f"Unknown type: {type(data)}"
@process_data.register
def _(data: str):
return f"Processing string: {data.upper()}"
@process_data.register
def _(data: list):
return f"Processing list of {len(data)} items"
print(process_data("hello")) # Processing string: HELLO
print(process_data([1, 2, 3])) # Processing list of 3 items
python code snippet end
The functools module empowers functional programming patterns that make code more efficient and reusable.
Pair functools with itertools to create sophisticated iterator-based solutions for data processing and analysis. The decorator patterns shown here build upon class concepts and integrate with exception handling for robust applications. Essential for optimizing parallel functions and works perfectly with statistical calculations that benefit from caching. Advanced generators benefit from yield from syntax for delegation and composability.
Reference: Python Functools Module Documentation