pythonadvanced15 minutes

Build a Decorator to Cache Function Results with Expiry

Create a Python decorator function that caches the results of an expensive function call, with support for automatic expiration of cached values after a given time-to-live (TTL).

Challenge prompt

Write a Python decorator named 'cache_with_expiry' that takes one parameter ttl (in seconds). When applied to a function, it caches its return values keyed by arguments, so repeated calls with the same arguments return cached results without recomputing. The cached results should expire and be removed if the TTL has passed since caching. Your solution should handle positional and keyword arguments properly, and ensure that different argument sets cache independently.

Guidance

  • Use a dictionary to store cached results with a key generated from the function arguments.
  • Store both the cached result and the timestamp when it was cached to check expiry.
  • Ensure that the decorator supports functions with any combination of positional and keyword arguments.
  • Use 'functools.wraps' to preserve the original function's metadata.

Hints

  • Consider using 'time.time()' to get the current timestamp in seconds.
  • To create a hashable key from function arguments, consider using a tuple for positional args and a frozenset for keyword args.
  • Remember to invalidate (remove) cached entries when their TTL has expired before returning cached results.

Starter code

import time
import functools

def cache_with_expiry(ttl):
    def decorator(func):
        cache = {}

        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            # Your caching logic here
            pass

        return wrapper
    return decorator

Expected output

When decorating a function that returns a time-dependent value, repeated calls with the same arguments within ttl seconds return the cached value instantly, but calls after ttl seconds recompute the value.

Core concepts

decoratorscachingfunction argumentstime-based expiration

Challenge a Friend

Send this duel to someone else and see if they can solve it.