Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes
Python

Boost Your Python Code with functools: LRU Cache, Partial, and Higher-Order Functions

Learn how Python's functools module can make your code faster and cleaner using lru_cache for caching, partial for argument freezing, and higher-order functions like wraps—with real-world examples from PythonSkillset.

July 2026 4 min read 1 views 0 hearts

Python's functools module is one of those hidden gems that can transform how you write everyday code. If you've ever found yourself writing repetitive boilerplate or duplicating logic, functools might be exactly what you need. Let's explore three of its most powerful tools: lru_cache, partial, and the concept of higher-order functions—and see how they make code cleaner, faster, and more readable.

The Problem with Repetition

Imagine you're working on a text processing pipeline at PythonSkillset, where you need to compute the word count for large documents multiple times. Without optimization, each call recalculates the entire result, even if the input hasn't changed. This wastes CPU cycles and slows down your application. That's where lru_cache steps in.

Caching Made Simple with lru_cache

lru_cache is a decorator that automatically stores the results of expensive function calls. The "LRU" stands for "Least Recently Used," which means it discards the least accessed results when the cache gets full. This is ideal for functions that are deterministic (same input always gives same output) and called repeatedly.

Here's a practical example from a real PythonSkillset article I wrote:

from functools import lru_cache

@lru_cache(maxsize=128)
def word_count(text):
    # Simulating an expensive operation
    words = text.split()
    return len(words)

Now, if you call word_count("Hello world") twice, the second call returns instantly from the cache. No recomputation needed. The maxsize parameter controls how many results to store—set it to None for unlimited cache, but be careful with memory.

Partial: Your Function Shortcut

Sometimes you need to call a function with the same arguments repeatedly. Instead of writing a wrapper, partial allows you to "freeze" some arguments of a function, creating a new, more specialized version.

Consider this scenario at PythonSkillset: you have a logging function that always writes to a specific file:

from functools import partial

def log(level, message, file):
    # Write to file
    print(f"[{level}] {message}", file=file)

# Instead of passing 'file' every time
import sys
log_error = partial(log, "ERROR", file=sys.stderr)
log_info = partial(log, "INFO", file=sys.stdout)

# Usage
log_error("Something went wrong")  # No need to pass file
log_info("All good")

This keeps your code DRY (Don't Repeat Yourself) and makes intentions clearer.

Higher-Order Functions: Functions That Create Functions

Both lru_cache and partial are examples of higher-order functions—functions that take or return other functions. Python's functools provides several such tools that let you compose behavior without writing boilerplate.

For instance, the reduce function (also from functools) lets you apply a cumulative operation to a sequence:

from functools import reduce
from operator import add

numbers = [1, 2, 3, 4]
total = reduce(add, numbers)  # 10

But more interesting is wraps, which preserves metadata when creating decorators. Without it, your decorated functions lose their name and docstring:

from functools import wraps

def my_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print("Before call")
        return func(*args, **kwargs)
    return wrapper

@my_decorator
def greet(name):
    """Says hello"""
    print(f"Hello {name}")

print(greet.__name__)  # 'greet', not 'wrapper'
print(greet.__doc__)   # 'Says hello', not None

Real-World Example at PythonSkillset

Last month, I optimized a PythonSkillset API endpoint that computed user statistics. The original code recalculated user rankings each request, even for cached data. Using lru_cache with a timeout (by clearing the cache periodically) cut response time from 500ms to under 10ms.

The code looked something like:

from functools import lru_cache
import time

@lru_cache(maxsize=1000)
def get_user_ranking(username):
    # Expensive database query and calculation
    time.sleep(0.5)
    return {"user": username, "rank": 42}

When to Use These Tools

  • lru_cache: Use for expensive, pure functions (no side effects) that are called frequently with the same arguments.
  • partial: Use when you have a function with many parameters, and you're often passing the same value for one or more arguments.
  • Higher-order functions in general: Use them to reduce repetitive patterns, especially when creating decorators or processing collections.

Final Thoughts

The functools module is a testament to Python's philosophy—simple, readable, and powerful without being overbearing. By incorporating lru_cache and partial into your daily work, you'll write code that's not only faster but also easier to understand and maintain.

Next time you catch yourself writing the same function call with identical arguments, or you notice a function being recomputed unnecessarily, remember: functools has your back. It's a small module that makes a big difference.

Happy coding at PythonSkillset!

Comments

Questions, corrections, and tips stay visible for everyone reading this page.

0 in thread

Join the discussion

Shown next to your comment.

Up to 4,000 characters

No comments yet

Be the first to leave a note — it helps the next reader.