Skip to main content Brad's PyNotes

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