DEV Community

francesco agati
francesco agati

Posted on

1

Python Decorators: Simplified Explanation

Python decorators are a powerful feature that allows you to modify or extend the behavior of functions or methods without changing their actual code. Let’s explore how decorators work with some simple examples.

Example 1: Logging Decorator

The logging decorator adds functionality to log information about when a function is called and what it returns.

def logger(func):
    def wrapper(*args, **kwargs):
        print(f'Calling {func.__name__} with args={args}, kwargs={kwargs}')
        result = func(*args, **kwargs)
        print(f'{func.__name__} returned {result}')
        return result
    return wrapper
Enter fullscreen mode Exit fullscreen mode

When you decorate a function with @logger, it prints messages before and after calling the function, showing its arguments and return value.

Example 2: Timing Decorator

The timing decorator measures how much time a function takes to execute.

import time

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f'{func.__name__} took {end_time - start_time} seconds to execute')
        return result
    return wrapper
Enter fullscreen mode Exit fullscreen mode

With @timer applied to a function, it calculates and prints the execution time in seconds.

Example 3: Authentication Decorator

The authentication decorator restricts access to a function based on user login status.

logged_in_users = ['alice', 'bob']

def authenticate(func):
    def wrapper(username, *args, **kwargs):
        if username in logged_in_users:
            return func(username, *args, **kwargs)
        else:
            raise PermissionError(f'User {username} is not logged in')
    return wrapper
Enter fullscreen mode Exit fullscreen mode

When decorated with @authenticate, the function can only be accessed by users in logged_in_users.

Example 4: Memoization Decorator

The memoization decorator caches results of a function to optimize performance for repeated calls with the same arguments.

def memoize(func):
    cache = {}

    def wrapper(*args):
        if args in cache:
            return cache[args]
        else:
            result = func(*args)
            cache[args] = result
            return result

    return wrapper
Enter fullscreen mode Exit fullscreen mode

Functions decorated with @memoize store computed results, returning cached results for identical arguments to avoid redundant calculations.

Using Decorators

@logger
def add(a, b):
    return a + b

@timer
def fibonacci(n):
    if n <= 1:
        return n
    else:
        return fibonacci(n-1) + fibonacci(n-2)

@authenticate
def protected_function(username, message):
    return f'{username}: {message}'

@memoize
def factorial(n):
    if n == 0 or n == 1:
        return 1
    else:
        return n * factorial(n-1)

# Testing each decorated function

print(add(3, 5))  # Output: Calling add with args=(3, 5), kwargs={}, add returned 8, 8

print(fibonacci(10))  # Output: fibonacci took 0.0 seconds to execute, 55

print(protected_function('alice', 'Hello!'))  # Output: alice: Hello!

try:
    print(protected_function('eve', 'Hi!'))  # Raises PermissionError
except PermissionError as e:
    print(e)

print(factorial(5))  # Output: 120

print(factorial(3))  # Output: 6
Enter fullscreen mode Exit fullscreen mode

Each decorator adds specific functionality to the decorated functions:

  • @logger logs function calls and returns.
  • @timer measures execution time.
  • @authenticate restricts function access based on user login.
  • @memoize caches function results to enhance performance.

Python decorators are versatile tools for adding cross-cutting concerns to functions, promoting code reuse and enhancing readability. They are widely used in frameworks and libraries to simplify and extend functionality without modifying core code.

Retry later

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

Retry later