Fundamentals 7 min read

An Introduction to Python's functools Module and Its Common Utilities

This article introduces Python's functools module, explaining key utilities such as partial functions, lru_cache, update_wrapper, wraps, cmp_to_key, singledispatch, FunctionTool, cache, and partialmethod, and provides practical code examples demonstrating how to create preset request functions, cache results, update signatures, and implement polymorphic behavior.

Test Development Learning Exchange
Test Development Learning Exchange
Test Development Learning Exchange
An Introduction to Python's functools Module and Its Common Utilities

Python's functools module is a standard library that provides a collection of higher‑order functions and decorators for functional programming, including tools for creating partial functions, caching results, and preserving function metadata.

Partial functions (partial) allow you to pre‑set some arguments of a callable, simplifying repeated calls. Example:

import requests
from functools import partial
# Create a request function with a default timeout
send_request = partial(requests.get, timeout=5)
response = send_request("https://api.example.com/data")
print("响应内容:", response.json())  # 响应内容: {'key': 'value'}

Cache decorator (lru_cache) memoizes function results to avoid redundant computation. Example:

import requests
from functools import lru_cache
@lru_cache(maxsize=32)
def get_user(id):
    response = requests.get(f"https://api.example.com/user/{id}")
    return response.json()
user = get_user(1)
print("用户:", user)  # 用户: {'id': 1, 'name': 'User 1'}

Updating function signatures (update_wrapper and wraps) keeps the original function's metadata after decoration. Example:

import requests
from functools import wraps
def log_request(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print("发送请求:", args[0])
        return func(*args, **kwargs)
    return wrapper

@log_request
def send_request(url):
    """发送请求并返回响应"""
    response = requests.get(url)
    return response.json()
result = send_request("https://api.example.com/data")
# 输出:
# 发送请求: https://api.example.com/data
# 响应内容: {'key': 'value'}

Comparison function (cmp_to_key) converts an old‑style comparator into a key function for sorting. Example:

from functools import cmp_to_key
def compare_by_age(u1, u2):
    return (u1['age'] > u2['age']) - (u1['age'] < u2['age'])
users = [
    {"name": "Alice", "age": 25},
    {"name": "Bob", "age": 30},
    {"name": "Charlie", "age": 20}
]
sorted_users = sorted(users, key=cmp_to_key(compare_by_age), reverse=True)
for user in sorted_users:
    print("用户:", user)
# 输出:
# 用户: {'name': 'Bob', 'age': 30}
# 用户: {'name': 'Alice', 'age': 25}
# 用户: {'name': 'Charlie', 'age': 20}

Single‑dispatch (singledispatch) enables type‑based polymorphic functions. Example:

from functools import singledispatch
@singledispatch
def process_data(data):
    raise NotImplementedError("Unsupported data type")
@process_data.register(int)
def _(data):
    return f"处理整数 {data}"
@process_data.register(str)
def _(data):
    return f"处理字符串 '{data}'"
result_int = process_data(123)
result_str = process_data("Hello")
print(result_int)  # 处理整数 123
print(result_str)  # 处理字符串 'Hello'

FunctionTool is a base class for building custom function utilities. Example:

from functools import FunctionTool
class MyTool(FunctionTool):
    def __init__(self, func):
        super().__init__(func)
        self.calls = 0
    def __call__(self, *args, **kwargs):
        self.calls += 1
        return super().__call__(*args, **kwargs)
@MyTool
def add(a, b):
    """添加两个数字"""
    return a + b
result = add(1, 2)
print("结果:", result)  # 结果: 3
print("调用次数:", add.calls)  # 调用次数: 1

Cache decorator (cache) provides a simple memoization without size limits. Example:

from functools import cache
@cache
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)
result = fibonacci(10)
print("斐波那契数列第10项:", result)  # 斐波那契数列第10项: 55

Partial method (partialmethod) creates class‑method partials. Example:

from functools import partialmethod
class MyClass:
    def __init__(self, value):
        self.value = value
    def echo(self, prefix):
        return f"{prefix}: {self.value}"
    echo_with_prefix = partialmethod(echo, "Prefix")
instance = MyClass("Hello World")
print(instance.echo_with_prefix())  # Prefix: Hello World
code examplesdecoratorslru-cachefunctoolspartial
Test Development Learning Exchange
Written by

Test Development Learning Exchange

Test Development Learning Exchange

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.