DEV Community

XZM27
XZM27

Posted on

Decorators in python

Decorators: end you everlasting confusion about decorators and its uses

Whenever going through github or any other codebase, we often come across somthing that looks unlike python.

@decorator
def my_function():
    pass
Enter fullscreen mode Exit fullscreen mode

This is known as a decorator in python and is extremely handy and powerful. A decorator is used when we need to change the behaviour of a function without changing the function itself. Makes sense? It will now.
It can be said that almost everything in python is an object. Functions are also objects(first class). Therefore we can assign functions to a variable.

def my_function():
    print("hello dev community")

#we can assign the function without executing to the variable func
func=my_function
Enter fullscreen mode Exit fullscreen mode

Functions are first class objects
They can be assigned to a varibale as shown earlier.
Moreover they can be passed as argument to another function and also nested into another function.

def outer(message):
    def inner():
        print("hi "+ message)
    return inner

hi = outer("dev community")
bye = outer("dev community")

#this executes the inner function.
hi()
bye()
Enter fullscreen mode Exit fullscreen mode

output

hi dev community
bye dev community
Enter fullscreen mode Exit fullscreen mode

Here we have two nested function outer and inner
outer returns inner without executing it. When we assign outer to a variable and execute the variable,it actually executes inner with the specific argument.
This is called a closure. Closures can avoid the use of global values and provides some form of data hiding. It can also provide an object oriented solution to the problem.

Decorators extensively use closures
Rather than taking message as an argument decorators take functions as arguments.Let's create a decorator step-by-step.

def decorator_function(original_function):
    def wrapper_function():
        #do something before the function
        print("hello from wrapper")
        return original_function()
    return wrapper_function

def display():
    print("hello from display")

decor_display = decorator_function(display)
decor_display()
Enter fullscreen mode Exit fullscreen mode

The code looks extremly similar to the closure we created earlier. We are now passing a function through decorated_function.

When we assign decor_display the decorator_function executes and returns wrapper_function. We then execute the wrapper_function stored in decor_display by invoking decor_display in the last line. Now the wrapper_function executes its print statement and the original_function which in our context is display and finally outputs:

hello from wrapper
hello from display
Enter fullscreen mode Exit fullscreen mode

That was a lot to take in for sure.Go through the process again and hopefully the logic will be clear.
Here we successfully managed to changed the behaviour of the display function by printing and extra line before it hello from wrapper. We did not change the display function itself but rather changed its behaviour using our decorator_function.

Python allows us to do this same thing using @decorator_function_name. Rather than assigning decorator_function to a variable we can assign it to any function using @decorator_function before the function.

def decorator_function(original_function):
    def wrapper_function():
        #do something before the function
        print("hello from wrapper")
        return original_function()
    return wrapper_function


#this works same as decorator_function(display)
@decorator_function
def display():
    print("hello from display")

display()
Enter fullscreen mode Exit fullscreen mode

output

hello from wrapper
hello from display
Enter fullscreen mode Exit fullscreen mode

Conclusions
Decorators are a powerful tool and is used in many codebases for various purposes such as logging, performance testing, perform caching, verifying permissions etc. If you find this tutorial useful do comment below. Thank you for reading and learning.

decorators part II->

Top comments (0)