close

Common decorators included with Python PREMIUM

Series: Decorators
Trey Hunner smiling in a t-shirt against a yellow wall
Trey Hunner
2 min. read Watch as video Python 3.10—3.14
Python Morsels
Watch as video
01:40

What decorators are included with Python?

Function caching for repeated calls

Python's functools module includes a cache decorator, which will cache the return values of a specific function.

from functools import cache
from math import isqrt

@cache
def is_prime(n):
    """Determine if a non-negative integer is prime."""
    if not isinstance(n, int) or n < 0:
        raise ValueError("Input must be a non-negative integer.")
    if n < 2:
        return False
    for i in range(2, isqrt(n) + 1):
        if n % i == 0:
            return False
    return True

Whenever a cache-decorated function is called with the same arguments that it has already been called with, a cached version of the return value will be used:

So if we pass a very large prime number to this is_prime function, it may take a few seconds to run to compute an answer:

>>> is_prime(10657331232548839)
True

But if we pass the same number again, it will return the same return value immediately.

>>> is_prime(10657331232548839)
True

The cache decorator keeps track of the arguments that a function is called with. For each unique argument signature, the return value is cached, and then reused if the function is called with the same arguments again.

Least-recently used cache

Python's functools module also includes an lru_cache decorator, which works like the cache decorator, except that a maximum cache size can also be supplied:

from functools import lru_cache
from math import isqrt


@lru_cache(maxsize=256)
def is_prime(n):
    """Determine if a non-negative integer is prime."""
    if not isinstance(n, int) or n < 0:
        raise ValueError("Input must be a non-negative integer.")
    if n < 2:
        return False
    for i in range(2, isqrt(n) + 1):
        if n % i == 0:
            return False
    return True

Note that the lru_cache decorator accepts an argument. We will see how to make decorators that accept arguments later.

Data classes

Python also includes class decorators, such as the dataclass decorator from Python's dataclasses module.

Here's a class called Transfer, which has three methods within it:

class Transfer:

    def __init__(self, sender, receiver, amount, memo):
        self.sender = sender
        self.receiver = receiver
        self.amount = amount
        self.memo = memo

    def __repr__(self):
        cls = type(self).__name__
        return (
            f"{cls}(sender={self.sender!r}, receiver={self.receiver!r}, " +
            f"amount={self.amount!r}, memo={self.memo!r})"
        )

    def __eq__(self, other):
        if not isinstance(other, Transfer):
            return NotImplemented
        mine = (self.sender, self.receiver, self.amount, self.memo)
        theirs = (other.sender, other.receiver, other.amount, other.memo)
        return mine == theirs

Instead of that 3-method Transfer class, we can use the dataclass decorator from Python's dataclasses module:

from dataclasses import dataclass

@dataclass
class Transfer:
    sender: str
    receiver: str
    amount: float
    memo: str

Note that the dataclass decorator is applied to classes, not functions. This type of decorator is often called a class decorator.

property, classmethod, contextmanager, and more

These are not the only three decorators included with Python.

Python also includes a property decorator, a classmethod decorator, a contextmanager decorator and other decorators.

There are also decorators included in third-party libraries. And you can even make your own decorators, which we'll be doing later.

Python Morsels
Watch as video
01:40
This is a free preview of a premium screencast. You have 1 preview remaining.