6.3. Decorator Types

  • Decorator function

  • Decorator method

  • Decorator class

6.3.1. Function Based Decorators

  • Decorator is a function which takes another object as an argument

  • Doesn't matter, whether this object is a function, class or method

Definition:

>>> def mydecorator(obj):
...     # do something with an object
...     return obj

Usage:

>>> @mydecorator
... def login():
...     return 'ok'
>>> @mydecorator
... class User:
...     def login(self):
...         return 'ok'
>>> class User:
...     @mydecorator
...     def login(self):
...         return 'ok'

6.3.2. Method Based Decorators

  • Decorator is a method which takes instance and another object as an argument

  • Doesn't matter, whether this object is a function, class or method

Definition:

>>> class MyClass:
...     @classmethod
...     def mydecorator(cls, obj):
...         # do something with an object
...         return obj

Usage:

>>> @MyClass.mydecorator
... def login():
...     return 'ok'
>>> @MyClass.mydecorator
... class User:
...     def login(self):
...         return 'ok'
>>> class User:
...     @MyClass.mydecorator
...     def login(self):
...         return 'ok'

6.3.3. Class Based Decorators

  • Decorator is a class which takes another object as an argument to __init__() method

  • Doesn't matter, whether this object is a function, class or method

Definition:

>>> class MyDecorator:
...     def __new__(cls, obj):
...         # do something with an object
...         return obj

Usage:

>>> @MyDecorator
... def login():
...     return 'ok'
>>> @MyDecorator
... class User:
...     def login(self):
...         return 'ok'
>>> class User:
...     @MyDecorator
...     def login(self):
...         return 'ok'

6.3.4. Use Case - 1

>>> def mydecorator(func):
...     print('init before')
...
...     def call(*args, **kwargs):
...         print('call before')
...         result = func(*args, **kwargs)
...         print('call after')
...         return result
...
...     print('init after')
...     return call
>>> @mydecorator
... def hello():
...     print('hi')
...
init before
init after
>>> hello()
call before
hi
call after

6.3.5. Use Case - 2

>>> class MyDecorator:
...     def __init__(self, func):
...         print('init before')
...         self.func = func
...         print('init after')
...
...     def __call__(self, *args, **kwargs):
...         print('call before')
...         result = self.func(*args, **kwargs)
...         print('call after')
...         return result
>>> @MyDecorator
... def hello():
...     print('hi')
...
init before
init after
>>> hello()
call before
hi
call after