DEV Community

Cover image for Python Decorators: Simplifying Code
Alfredo Pasquel
Alfredo Pasquel

Posted on

Python Decorators: Simplifying Code

Decorators in Python are a powerful tool that allow you to modify the behavior of functions or methods without changing their source code. They provide a clean way to add functionality and are widely used for logging, enforcing rules, and optimizing performance.

In this post, we'll look at six common Python decorators with simple examples.

1 - @staticmethod: Define Static Methods

The @staticmethod decorator creates methods that don’t access instance (self) or class (cls) data. It behaves like a regular function but can be called from the class or an instance.

Example:

class MyClass:
    @staticmethod
    def greet():
        return "Hello from static method!"

Enter fullscreen mode Exit fullscreen mode

2 - @classmethod: Define Class Methods

The @classmethod decorator lets you define methods that take the class (cls) as the first argument. This is useful for factory methods or altering class state.

Example:

class MyClass:
    count = 0

    @classmethod
    def increment_count(cls):
        cls.count += 1
Enter fullscreen mode Exit fullscreen mode

3 - @property: Define Read-Only Attributes

The @property decorator allows methods to be accessed like attributes. It’s useful when you want to control access to a property without exposing the internal implementation.

Example:

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

    @property
    def area(self):
        return 3.14 * self._radius ** 2
Enter fullscreen mode Exit fullscreen mode

4 - @functools.lru_cache: Cache Expensive Function Results

The @lru_cache decorator (from functools) caches the results of function calls to avoid recomputation. This can significantly improve performance for expensive or frequently called functions.

Example:

from functools import lru_cache

@lru_cache(maxsize=32)
def expensive_computation(x):
    return x ** 2
Enter fullscreen mode Exit fullscreen mode

5 - @functools.wraps: Preserve Metadata in Custom Decorators

When writing custom decorators, the @wraps decorator preserves the metadata (name, docstring) of the original function, ensuring that introspection tools still work.

Example:

from functools import wraps

def my_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper
Enter fullscreen mode Exit fullscreen mode

6 - @dataclass: Simplify Class Definitions

The @dataclass decorator (from the dataclasses module) automatically generates methods like init() and repr() for classes. It’s perfect for data-holding classes.

Example:

from dataclasses import dataclass

@dataclass
class Point:
    x: int
    y: int
Enter fullscreen mode Exit fullscreen mode

Conclusion

Python decorators like @staticmethod, @classmethod, @property, @lru_cache, @wraps, and @dataclass help write cleaner and more efficient code by wrapping functionality around methods and functions. They are versatile tools that can simplify many programming tasks.

Sources

Python Decorator Definition
@staticmethod
@classmethod
@property
@functools.lru_cache
@functools.wraps
@dataclass

Top comments (0)