Decorators in Python

Aditya Mahamuni
3 min readDec 21, 2022

--

Python

Decorators are a powerful and useful tool in Python, allowing you to modify the behavior of a function without changing its code. They are implemented using a special syntax, starting with the @ symbol followed by the name of the decorator function.

To create a decorator, you define a function that takes another function as an argument and returns a modified version of that function.

For example, here is a simple decorator that adds two to the result of a function:

def add_two(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result + 2
return wrapper

To use this decorator, you can apply it to any function by using the @ symbol followed by the name of the decorator:

@add_two
def calculate(x, y):
return x + y

result = calculate(3, 4)
print(result) # prints 9

In this example, the calculate function is wrapped in the wrapper function defined in the add_two decorator. When the calculate function is called, the wrapper function is executed instead, which calls the original calculate function and adds two to its result.

Decorators are often used to add functionality to an existing function without changing its code. For example, you might use a decorator to log the arguments and return value of a function, or to cache the results of a function to improve its performance.

One important thing to note is that decorators are applied in the order in which they appear. For example:

def add_two(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result + 2
return wrapper

def multiply_by_three(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result * 3
return wrapper

@add_two
@multiply_by_three
def calculate(x, y):
return x + y

result = calculate(3, 4)
print(result) # prints 23

In this case, the calculate function is first decorated with the decorator multiply_by_three and then with the add_two decorator. This means that the wrapper function defined in the multiply_by_three decorator is applied first, followed by the wrapper function defined in the add_two decorator.

Decorators are a powerful tool that can be used to modify the behavior of functions in a concise and elegant way. They are commonly used in Python to add functionality to existing code without changing its implementation.

Decorators can also be useful for modifying the behavior of class methods. For example, you might use a decorator to add a logging feature to all the methods in a class:

def log_methods(cls):
for name, value in vars(cls).items():
if callable(value):
setattr(cls, name, log_method(value))
return cls
def log_method(func):
def wrapper(*args, **kwargs):
print(f"Calling method {func.__name__} with args {args} and kwargs {kwargs}")
result = func(*args, **kwargs)
print(f"Method {func.__name__} returned {result}")
return result
return wrapper

@log_methods
class MyClass:
def method1(self, x):
return x * 2

def method2(self, x, y):
return x + y

obj = MyClass()
obj.method1(10)
obj.method2(5, 6)
Output:
Calling method method1 with args (<__main__.MyClass object at 0x0000024E0439E910>, 10) and kwargs {}
Method method1 returned 20
Calling method method2 with args (<__main__.MyClass object at 0x0000024E0439E910>, 5, 6) and kwargs {}
Method method2 returned 11

In this example, the log_methods decorator applies the log_method decorator to all the functions in the class.

--

--

Aditya Mahamuni
Aditya Mahamuni

No responses yet