Decorators are a very powerful and useful tool in Python since it allows programmers to modify the behaviour of function or class. Decorators allow us to wrap another function in order to extend the behaviour of the wrapped function, without permanently modifying it.
We can define a decorator as a class in order to do that, we have to use a __call__ method of classes. When a user needs to create an object that acts as a function then function decorator needs to return an object that acts like a function, so __call__ can be useful. For Example
Python3
class MyDecorator:
def __init__( self , function):
self .function = function
def __call__( self ):
self .function()
@MyDecorator
def function():
print ( "GeeksforGeeks" )
function()
|
Class Decorator with *args and **kwargs :
In order to use class decorator with argument *args and **kwargs we used a __call__ function and passed both the argument in a given function
Python3
class MyDecorator:
def __init__( self , function):
self .function = function
def __call__( self , * args, * * kwargs):
self .function( * args, * * kwargs)
@MyDecorator
def function(name, message = 'Hello' ):
print ( "{}, {}" . format (message, name))
function( "geeks_for_geeks" , "hello" )
|
Output:
hello, geeks_for_geeks
Class Decorator with return statement :
In the given example the functions did not return anything so there is not any issue, but one may need the returned value. So we use return statement with the class decorator.
Python3
class SquareDecorator:
def __init__( self , function):
self .function = function
def __call__( self , * args, * * kwargs):
result = self .function( * args, * * kwargs)
return result
@SquareDecorator
def get_square(n):
print ( "given number is:" , n)
return n * n
print ( "Square of number is:" , get_square( 195 ))
|
Output:
given number is: 195
Square of number is: 38025
Using class Decorators to print Time required to execute a program :
In order to print time required to execute a program, we use __call__ function and use a time module so that we can get a execute time of a program
Python3
from time import time
class Timer:
def __init__( self , func):
self .function = func
def __call__( self , * args, * * kwargs):
start_time = time()
result = self .function( * args, * * kwargs)
end_time = time()
print ( "Execution took {} seconds" . format (end_time - start_time))
return result
@Timer
def some_function(delay):
from time import sleep
sleep(delay)
some_function( 3 )
|
Output:
Execution took 3.003122091293335 seconds
Checking error parameter using class decorator :
This type of class decorator is most frequently used. This decorator checks parameters before executing the function preventing the function to become overloaded and enables it to store only logical and necessary statements.
Python3
class ErrorCheck:
def __init__( self , function):
self .function = function
def __call__( self , * params):
if any ([ isinstance (i, str ) for i in params]):
raise TypeError( "parameter cannot be a string !!" )
else :
return self .function( * params)
@ErrorCheck
def add_numbers( * numbers):
return sum (numbers)
print (add_numbers( 1 , 2 , 3 ))
print (add_numbers( 1 , '2' , 3 ))
|
Output :
6
TypeError: parameter cannot be a string !!
Whether you're preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape,
GeeksforGeeks Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we've already empowered, and we're here to do the same for you. Don't miss out -
check it out now!
Last Updated :
23 Jul, 2021
Like Article
Save Article