Python Decorators: How to Use Decorators in Python
In Python, everything is an object from class to function. In Python, names that we define are simply the identifiers bound to these objects. Functions are no exceptions to that fact because they are objects too with attributes. In Python, Functions are the first-class objects, which means the following.
- Functions are objects; they can be referenced to another function, passed to a variable, and returned from other functions as well.
- Functions can be defined inside another function and can also be passed as an argument to another function.
Decorators provide the simple syntax for calling higher-order functions.
Decorators are a powerful and useful feature in Python since it allows programmers to modify the behavior of function or class. By definition, a decorator is a function that takes another function and extends its behavior without explicitly changing it.
Let us take a simple function and then extend its behavior to make a decorator.
# app.py def square(x): return x * x print(square(16))
The above function returns merely the square of the passing argument as a number.
See the output in the console.
Now, let us extends its behavior. Let us create a Decorator. Write the following code inside the app.py file.
# app.py def square(x): return x * x def decorator(func, x): output = func(x) output = output - x return output print(decorator(square, 16))
In the above example, we have created one more function called a decorator. You can name it anything.
Then I have passed two arguments, and one of the square() function and the other is the number that we need the square of. Then we get the output of the square and use that output further to perform a further calculation. We can get the following output of the above decorator.
The function can return another function
Let us take an example where a function returns another function.
# app.py def decorator(): def square(x): return x * x return square(15) func = decorator() print(func)
In the above example, we are calling the decorator() function, which is returning another function called square().
Functions and methods are called callable because they can be called.
Any object that implements the particular method called __call()__ is termed callable. So, in the most basic sense, the decorator is the callable that returns a callable.
Without calling a function, a function will not be executed that is why we are calling that square() function from the decorator() function and finally we get the output. The output is the following.
Decorating Functions in Python
Let us take the following example.
# app.py def smart_divide(func): def inner(a,b): print("I am going to divide",a,"and",b) if b == 0: print("Whoops! cannot divide") return return func(a,b) return inner @smart_divide def divide(a,b): return a/b print(divide(9, 15))
In the above example, we are dividing one number to another number. Here one gotcha is that if the second number should not be zero. That is why we are extending its functionality by adding a logic that if the second parameter is 0, then we should be returned from the function and not perform the division.
That is why when we call the divide function, just above we have written the @smart_divide decorator. That means we are using smart division and not regular division.
It is extending the functionality of simple division. The output of the above decorator is the following.
Finally, Python Decorators Example is over.