Subjects

All subjects Django Java Python React Spring Boot JavaScript PHP
Sign Up Free
Interview question

How do you write a decorator that accepts arguments? Arguments accept करने वाला decorator कैसे लिखें?

Answer

A decorator with arguments needs an extra layer of nesting - an outer function that takes the decorator arguments and returns the actual decorator function.

def repeat(times):  # outer function accepts the decorator's OWN arguments
    def decorator(func):  # actual decorator
        def wrapper(*args, **kwargs):
            result = None
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(times=3)
def greet(name):
    print(f'Hello, {name}')

greet('John')
# Hello, John
# Hello, John
# Hello, John

# What @repeat(times=3) actually does under the hood:
def greet2(name):
    print(f'Hello, {name}')
greet2 = repeat(times=3)(greet2)  # repeat(3) returns 'decorator', which wraps greet2

# Real-world example: retry decorator with configurable attempts
def retry(max_attempts=3):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for attempt in range(max_attempts):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    print(f'Attempt {attempt + 1} failed: {e}')
            raise Exception('All attempts failed')
        return wrapper
    return decorator

@retry(max_attempts=5)
def unreliable_network_call():
    # ... code that might fail ...
    pass

Arguments लेने वाले decorator को एक extra nesting layer चाहिए - outer function जो decorator के अपने arguments लेता है और असली decorator function return करता है।

def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            result = None
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(times=3)
def greet(name):
    print(f'Hello, {name}')

greet('John')
# तीन बार print होगा

# @repeat(times=3) असल में क्या करता है:
def greet2(name):
    print(f'Hello, {name}')
greet2 = repeat(times=3)(greet2)

# Retry decorator - configurable attempts
def retry(max_attempts=3):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for attempt in range(max_attempts):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    print(f'Attempt {attempt + 1} fail: {e}')
            raise Exception('सभी attempts fail हुए')
        return wrapper
    return decorator

Was this answer clear?