2. Functions are Objects
• They can be assigned to other variables.
• A function can be defined inside another
function.
• A function can return another function.
• A function can take other function as an
arguments.
3. Decorators
• A decorator is used to wrap a function.
• It gives new functionality without changing
the original function.
Syntax :
@decorator_function
def my_func:
…………………….
…………………….
def decorater_function():
……………………….
……………………….
This is equivalent to :
my_func =
decorator_function(my_func)
4. How to define a decorator function?
• It takes a function (the one being decorated),
wrap it in a wrapper function and then return
the wrapper function.
def decorator_function(decorated_function):
def wrapper_function():
------------------------------------
------- some code ----------------
decorated_function()
------------------------------------
return wrapper_function
5. • There are user defined and in built decorators.
staticmethod and classmethod are
example of in built decorators.
• There can be more that one decorator for one
function. They are executed using stack.
6. Example
def helloSolarSystem(old_function):
def wrapper_function():
print "Hello Solar System"
old_function()
return wrapper_function
def helloGalaxy(old_function):
def wrapper_function():
print "Hello Galaxy"
old_function()
return wrapper_function
@helloGalaxy
@helloSolarSystem
def hello():
print "Hello World"
hello()
The output will be -
Hello Galaxy
Hello Solar System
Hello World
First all decorators are
pushed into a stack
Then, at last, they are
popped one by one.
7. Passing argument to the decorated function
The wrapper function should accept the arguments which are being passed to the
function being decorated.
def helloSolarSystem(old_function):
def wrapper_function(planet=None):
print "Hello Solar System"
old_function(planet)
return wrapper_function
@helloSolarSystem
def hello(planet=None):
if planet:
print "Hello "+planet
else:
print "Hello World"
hello("Mars")
hello()
Output
Hello Solar System
Hello Mars
Hello Solar System
Hello World
8. • You can also define wrapper for class method.
But their first argument should be self
• You can define general wrapper function using
*args, **kwargs.
9. Class Decorators
• Class decorators are similar to function
decorators.
• They are run at the end of a class statement to
rebind a class name to a callable.
• They can be used to manage class when they are
created.
• They can be used to insert a layer of wrapper
logic to manage instances.
• Remember both class and class instance are
object in python.
10. Syntax
• Syntax is similar to function decorator.
Class definition-
@class_decorator
class My_Class:
-------------
-------------
Decorator definition –
def class_decorator(cls):
---------------
---------------
This is equivalent to
My_Class =
class_decorator(My_Class)
11. Example – Singleton Class
instances = {} #dictionary to hold class and their only instance
def getInstance(klass,*args): #this function is used by decorator
if klass not in instances:
instances[klass]=klass(*args)
return instances[klass]
def singelton(klass): #decorator function
def onCall(*args):
return getInstance(klass,*args)
return onCall
@singelton
class Star:
def __init__(self,name):
self.name=name
#A solar system should have only one star
sun = Star('Sun')
print sun.name
taurus = Star('Taurus')
print taurus.name
Output -
Sun
Sun
Only one instance of Star is allowed.