Innovate anywhere, anytime withruncode.io Your cloud-based dev studio.
Python

Programming with Python: Decorators

2022-07-19

Python decorators support aspect-oriented programming. It is used to add or modify the code in functions or classes. Using decorators will provide security, tracing, looking etc Let see an example:

@fundecorator
def myfunc():
print "This is my function"

The above example has a function myfunc() with a decorator @fundecorator. The symbol @ tell that the type of the name is a decorator. Some points regarding decorators: -- Decorators can be function or class -- The class that is used as a decorator must implement __call__ -- In a class, decorator  arguments are optional whereas a function decorator must have arguments. Decorators are of two types: 1. Class decorators: - In this, we use class as a decorator to decorate functions/classes. For example:

>>> class mydecorator(object):
...   def __init__(self, f):
...     self.f = f
...   def __call__(self):
...     print "Start of", self.f.__name__
...     self.f()
...     print "End of", self.f.__name__
...
>>> @mydecorator
... def func1():

...   print "This is function 1"
...
>>> @mydecorator
... def func2():
...   print "This is function 2"
...

The output is:

>>> func1()
Start of func1
This is function 1
End of func1
>>> func2()
Start of func2
This is function 2
End of func2

Class decorators without arguments: The above example is considered under this category. There are no decorator arguments in __init__. So the control is passed to the constructor f() which will take the function to be decorated as input. __call__ will be invoked only after the decorated function is called. Class decorators with arguments: These are the class decorators which take input arguments. For example:

#decorators.py
class mydecorator(object):
def __init__(self, arg1, arg2, arg3):
self.arg1 = arg1
self.arg2 = arg2
self.arg3 = arg3
def __call__(self, f):
def sum_of_args(*args):
print("Decorator arguments:", self.arg1, self.arg2, self.arg3)
f(*args)
print("Sum of decorator arguments: ", (self.arg1+self.arg2+self.arg3))
return sum_of_args

@mydecorator(5, 10, 15)
def sayHello(a1, a2, a3, a4):
print('sayhello() arguments:', a1, a2, a3, a4)

print("Calling sayHello()")
sayHello("say", "hi", "hello", "world")

The output for the above program will be:

~$ python decorators.py
Calling sayHello()
('Decorator arguments:', 5, 10, 15)
('sayhello() arguments:', 'say', 'hi', 'hello', 'world')
('Sum of decorator arguments: ', 30)

2. Function decorators:- In this we use function as decorator to decorate functions/classes. For example:

>>> def mydecorator(f):
...   def myfun():
...     print "Start of", f.__name__
...     f()
...     print "End of", f.__name__
...   myfun.__name__ = f.__name__
...   return myfun
...
>>> @mydecorator
... def func1():
...   print "This is function 1"
...
>>> @mydecorator
... def func2():
...   print "This is function 2"
...

The output will be same as the output for Type 1.