Decorators in Python

Decorators in Python

A decorator is a function that modifies the behavior of another function without permanently modifying it. Decorators are a powerful tool that use closure functions.

Basic Concept

A decorator:

  1. Takes a function as input
  2. Returns a modified function (or a new function)
  3. Uses the @decorator_name syntax

Simple Example

python

def simple_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper

@simple_decorator
def say_hello():
    print("Hello!")

# Using the decorated function
say_hello()

Output:

text

Something is happening before the function is called.
Hello!
Something is happening after the function is called.

Equivalent Without @ Syntax

python

def say_hello():
    print("Hello!")

# Manual decoration
decorated_hello = simple_decorator(say_hello)
decorated_hello()

Decorator for Functions with Arguments

python

def smart_divide(func):
    def wrapper(a, b):
        print(f"Dividing {a} by {b}")
        if b == 0:
            print("Cannot divide by zero!")
            return
        return func(a, b)
    return wrapper

@smart_divide
def divide(a, b):
    return a / b

print(divide(10, 2))  # Output: Dividing 10 by 2 → 5.0
print(divide(10, 0))  # Output: Dividing 10 by 0 → Cannot divide by zero!

Decorator with Any Number of Arguments

python

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

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

@logger
def multiply(x, y, z=1):
    return x * y * z

add(3, 5)
multiply(2, 3, z=4)

Output:

text

Calling add with args: (3, 5), kwargs: {}
add returned: 8
Calling multiply with args: (2, 3), kwargs: {'z': 4}
multiply returned: 24

Practical Example: Timing Function Execution

python

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__} executed in {end_time - start_time:.4f} seconds")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(2)
    return "Done!"

slow_function()  # Output: slow_function executed in 2.0002 seconds

Chaining Decorators

python

def bold(func):
    def wrapper():
        return "<b>" + func() + "</b>"
    return wrapper

def italic(func):
    def wrapper():
        return "<i>" + func() + "</i>"
    return wrapper

@bold
@italic
def hello():
    return "Hello World"

print(hello())  # Output: <b><i>Hello World</i></b>

Decorator with Arguments

python

def repeat(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for i in range(n):
                print(f"Call {i+1}:")
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(3)
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")

Output:

text

Call 1:
Hello, Alice!
Call 2:
Hello, Alice!
Call 3:
Hello, Alice!

Why Use Decorators?

  • Code Reuse: Avoid repetitive code
  • Separation of Concerns: Keep business logic separate from cross-cutting concerns
  • Readability: Makes code more readable and maintainable
  • Extensibility: Easy to add/remove functionality

Decorators are widely used in web frameworks (like Flask, Django), testing, logging, and many other areas of Python programming!

Similar Posts

  • start(), end(), and span()

    Python re start(), end(), and span() Methods Explained These methods are used with match objects to get the positional information of where a pattern was found in the original string. They work on the result of re.search(), re.match(), or re.finditer(). Methods Overview: Example 1: Basic Position Tracking python import re text = “The quick brown fox jumps over the lazy…

  • positive lookbehind assertion

    A positive lookbehind assertion in Python’s re module is a zero-width assertion that checks if the pattern that precedes it is present, without including that pattern in the overall match. It’s the opposite of a lookahead. It is written as (?<=…). The key constraint for lookbehind assertions in Python is that the pattern inside the…

  • Currency Converter

    Challenge: Currency Converter Class with Accessors & Mutators Objective: Create a CurrencyConverter class that converts an amount from a foreign currency to your local currency, using accessor and mutator methods. 1. Class Properties (Instance Variables) 2. Class Methods 3. Task Instructions

  • Programs

    Weekly Wages Removing Duplicates even ,odd Palindrome  Rotate list Shuffle a List Python random Module Explained with Examples The random module in Python provides functions for generating pseudo-random numbers and performing random operations. Here’s a detailed explanation with three examples for each important method: Basic Random Number Generation 1. random.random() Returns a random float between 0.0 and 1.0 python import…

  • Formatting Date and Time in Python

    Formatting Date and Time in Python Python provides powerful formatting options for dates and times using the strftime() method and parsing using strptime() method. 1. Basic Formatting with strftime() Date Formatting python from datetime import date, datetime # Current date today = date.today() print(“Date Formatting Examples:”) print(f”Default: {today}”) print(f”YYYY-MM-DD: {today.strftime(‘%Y-%m-%d’)}”) print(f”MM/DD/YYYY: {today.strftime(‘%m/%d/%Y’)}”) print(f”DD-MM-YYYY: {today.strftime(‘%d-%m-%Y’)}”) print(f”Full month: {today.strftime(‘%B %d, %Y’)}”) print(f”Abbr…

  • Generators in Python

    Generators in Python What is a Generator? A generator is a special type of iterator that allows you to iterate over a sequence of values without storing them all in memory at once. Generators generate values on-the-fly (lazy evaluation) using the yield keyword. Key Characteristics Basic Syntax python def generator_function(): yield value1 yield value2 yield value3 Simple Examples Example…

Leave a Reply

Your email address will not be published. Required fields are marked *