Decorators in Python
In programming, decorator is a design pattern that adds additional responsibilities to an object dynamically. In Python, a function is the first-order object. So, a decorator in Python adds additional responsibilities/functionalities to a function dynamically without modifying a function.
In Python, a function can be passed as an argument to another function. It is also possible to define a function inside another function, and a function can return another function.
So, a decorator in Python is a function that receives another function as an argument. The behavior of the argument function is extended by the decorator without actually modifying it. The decorator function can be applied over a function using the @decorator syntax.
Let's understand the decorator in Python step-by-step.
Consider that we have the greet()
function, as shown below.
def greet():
print('Hello! ', end='')
Now, we can extend the above function's functionality without modifying it by passing it to another function, as shown below.
def mydecorator(fn):
fn()
print('How are you?')
mydecorator(greet) #output:Hello! How are you?
Above, the mydecorator()
function takes a function as an argument. It calls the argument function and also prints some additional things. Thus, it extends the functionality of the greet()
function without modifying it.
However, it is not the actual decorator.
The mydecorator()
is not a decorator in Python. The decorator in Python can be defined over any appropriate function using the @decorator_function_name
syntax to extend the functionality of the underlying function.
The following defines the decorator for the above greet()
function.
def mydecorator(fn):
def inner_function():
fn()
print('How are you?')
return inner_function
The mydecorator()
function is the decorator function that takes a function (any function that does not take any argument) as an argument.
The inner function inner_function()
can access the outer function's argument, so it executes some code before or after to extend the functionality before calling the argument function.
The mydecorator
function returns an inner function.
Now, we can use mydecorator
as a decorator to apply over a function that does not take any argument, as shown below.
@mydecorator
def greet():
print('Hello! ', end='')
Now, calling the above greet()
function will give the following output.
greet() #output:Hello! How are you?
The mydecorator
can be applied to any function that does not require any argument. For example:
@mydecorator
def dosomething():
print('I am doing something.', end='')
dosomething() #output: I am doing something. How are you?
The typical decorator function will look like below.
def mydecoratorfunction(some_function): # decorator function
def inner_function():
# write code to extend the behavior of some_function()
some_function() # call some_function
# write code to extend the behavior of some_function()
return inner_function # return a wrapper function
Built-in Decorators
Python library contains many built-in decorators as a shortcut of defining properties, class method, static methods, etc.
Decorator | Description |
---|---|
@property | Declares a method as a property's setter or getter methods. |
@classmethod | Declares a method as a class's method that can be called using the class name. |
@staticmethod | Declares a method as a static method. |
Learn about the built-in decorator @property next.