Decorators are a powerful feature in Python that allow us to modify the behavior of functions and classes without changing their source code.
Function decorators in Python are a way to modify the behavior of a function by wrapping it with another function. Decorators provide a clean and concise way to add functionality to existing functions without modifying their source code.
The basic syntax of a function decorator is as follows:
@decorator
def function():
# Function body
Here's an example to illustrate how function decorators work:
def uppercase_decorator(func):
def wrapper():
original_result = func()
modified_result = original_result.upper()
return modified_result
return wrapper
@uppercase_decorator
def greet():
return "hello"
result = greet()
print(result) # Output: "HELLO"
In this example, we define a decorator function called uppercase_decorator
. It takes a function func
as an argument and defines a nested function wrapper
. The wrapper
function modifies the result of the original function by converting it to uppercase. The decorator function then returns the wrapper
function.
We apply the uppercase_decorator
to the greet
function using the @
syntax. When we call greet()
, the decorator is automatically applied, and the result is modified to uppercase.
Decorators are a powerful tool for adding functionality such as logging, authentication, or caching to functions in a reusable and modular way.
In addition to decorating functions, decorators can also be used to modify the behavior of classes and their methods. This allows us to add extra functionality or modify the behavior of methods without directly modifying the class code.
Here's an example of decorating a class method:
def uppercase_decorator(func):
def wrapper(self):
original_result = func(self)
modified_result = original_result.upper()
return modified_result
return wrapper
class Greeting:
@uppercase_decorator
def greet(self):
return "hello"
g = Greeting()
result = g.greet()
print(result) # Output: "HELLO"
In this example, we define a class called Greeting
with a method called greet
. We apply the uppercase_decorator
to the greet
method using the @
syntax. When we call g.greet()
, the decorator is automatically applied to modify the result to uppercase.
Decorating classes and methods allows us to extend or modify their behavior in a flexible and reusable manner. It is particularly useful for adding cross-cutting concerns, such as logging or timing, to multiple methods or classes.