Skip to content

Python functools Module: Detailed Overview and Examples

The functools module in Python provides higher-order functions that act on or return other functions. These utilities help with common functional programming patterns and can make your code more concise and expressive.

Key Functions and Methods

1. functools.partial

Description

functools.partial allows you to fix a certain number of arguments of a function and generate a new function.

Syntax

functools.partial(func, /, *args, **keywords)

Example

import functools

def multiply(x, y):
    return x * y

# Create a new function that multiplies by 2
double = functools.partial(multiply, 2)

print(double(5))  # Output: 10

2. functools.reduce

Description

functools.reduce applies a binary function cumulatively to the items of a sequence, from left to right, to reduce the sequence to a single value.

Syntax

functools.reduce(function, iterable[, initializer])

Example

import functools

# Sum all elements in a list
result = functools.reduce(lambda x, y: x + y, [1, 2, 3, 4, 5])
print(result)  # Output: 15

3. functools.lru_cache

Description

functools.lru_cache is a decorator that caches the results of function calls with least-recently-used (LRU) eviction.

Syntax

functools.lru_cache(maxsize=128, typed=False)

Example

import functools

@functools.lru_cache(maxsize=100)
def factorial(n):
    if n == 0:
        return 1
    return n * factorial(n-1)

print(factorial(5))  # Output: 120

4. functools.singledispatch

Description

functools.singledispatch is a decorator that transforms a function into a single-dispatch generic function.

Syntax

@functools.singledispatch
def func(arg, *args, **kw):
    ...

Example

import functools

@functools.singledispatch
def process(value):
    print(f"Default: {value}")

@process.register(int)
def _(value):
    print(f"Integer: {value}")

@process.register(str)
def _(value):
    print(f"String: {value}")

process(10)    # Output: Integer: 10
process("hi")  # Output: String: hi
process([1, 2, 3])  # Output: Default: [1, 2, 3]

5. functools.update_wrapper and functools.wraps

Description

functools.update_wrapper is used to update a wrapper function to look more like the wrapped function by copying attributes. functools.wraps is a decorator that applies update_wrapper to the wrapper function.

Syntax

functools.update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
functools.wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)

Example

import functools

def my_decorator(f):
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        print("Something is happening before the function is called.")
        result = f(*args, **kwargs)
        print("Something is happening after the function is called.")
        return result
    return wrapper

@my_decorator
def say_hello(name):
    return f"Hello, {name}"

print(say_hello("Alice"))
print(say_hello.__name__)  # Output: say_hello

6. functools.total_ordering

Description

functools.total_ordering is a class decorator that fills in missing comparison methods (<, <=, >, >=) based on __eq__ and one other method.

Syntax

@functools.total_ordering
class MyClass:
    ...

Example

import functools

@functools.total_ordering
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __eq__(self, other):
        return self.age == other.age

    def __lt__(self, other):
        return self.age < other.age

# Create instances
person1 = Person("Alice", 30)
person2 = Person("Bob", 25)

print(person1 > person2)  # Output: True
print(person1 <= person2)  # Output: False

7. functools.cached_property

Description

functools.cached_property transforms a method into a property whose value is computed once and then cached as a normal attribute for the life of the instance.

Syntax

class MyClass:
    @functools.cached_property
    def my_property(self):
        ...

Example

import functools

class Circle:
    def __init__(self, radius):
        self.radius = radius

    @functools.cached_property
    def area(self):
        print("Computing area")
        return 3.14159 * self.radius * self.radius

c = Circle(10)
print(c.area)  # Output: Computing area 314.159
print(c.area)  # Output: 314.159

Conclusion

The functools module in Python provides a variety of higher-order functions that can greatly simplify and enhance your code. From partial application of functions with partial to memoization with lru_cache, and method overloading with singledispatch, the module offers powerful tools for functional programming and optimization. By leveraging these utilities, you can write more concise, readable, and efficient Python code.