p

python tutorial - Python Decorators | Function Decorators in Python | Introduction - learn python - python programming



Decorators

  • "Decoration is a way to specify management code for functions and classes." ... "A decorator itself is a callable that returns a callable."
  • A function object is a callable. So, the previous statement can be translated into:
  • A decorator is a function that takes a function object as its argument, and returns a function object, and in the process, makes necessary modifications to the input function, possibly enhancing it.
  • Decorator wraps a function without modifying the function itself. The result of the wrapping?
    • Adds functionality of the function.
    • Modifies the behavior of the function.

Function Decorators

  • Let's start with a function in Python. To understand decorators, we need to know the full scope of capabilities of Python functions.
  • Everything in Python is an object. Function is not an exception.
>>> a=10
>>> def f():
...     pass
...
>>> class MyClass():
...     pass
...
>>> print dir()
['MyClass', '__builtins__', '__doc__', '__name__', '__package__', 'a', 'f']
click below button to copy the code. By Python tutorial team
  • As we can see, f() is an object, and it's not different from classes (MyClass) or variables (a).
  • We can assign a function to a variable, so the following lines of code is legally perfect.
def func():
   print "func()"

funcObj = func
funcObj()
click below button to copy the code. By Python tutorial team
  • Functions can be passed around in the same way other types of object such as strings, integers, lists, etc.
  • Another face of a function in Python is it can accept a function as an argument and return a new function object as shown below.
def myFunction(in_function):
   def out_function():
      pass
   return out_function
click below button to copy the code. By Python tutorial team
  • The myFunction is indeed a decorator because by definition a decorator is a function that takes a function object as its argument, and returns a function object.
  • If we elaborate a little bit more on the function we just defined:
def myFunction(in_function):
   def out_function():
      print "Entry: ", in_function.__name__
      in_function()
      print "Exit: ", in_function.__name__
   return out_function
click below button to copy the code. By Python tutorial team

How we invoke our decorator ?

  • Let's look at the example below. We put a simple_function into the decorator (myFunction) as an argument, and get a enhanced_function as a return value from the decorator.
def simple_function():
   pass
	
enhanced_function = myFunction(simple_function)
click below button to copy the code. By Python tutorial team
  • In many cases, we use the same name for the returned function objects as the name of the input function. So, practically, the code should look like this:
def simple_function():
   pass
	
simple_function = myFunction(simple_function)
click below button to copy the code. By Python tutorial team
  • If we apply the decorator syntax to the code above:
@myFunction
def simple_function():
   pass
click below button to copy the code. By Python tutorial team
  • Note that the first line @myFunctionas is not a decorator but rather a decorator line or an annotation line, etc.
  • The @ indicates the application of the decorator. A decorator is the function itself which takes a function, and returns a new function. In our case, it is myFunction.
  • When the compiler passes over this code, simple_function() is compiled and the resulting function object is passed to the myFunction code, which does something to produce a function-like object that is then substituted for the original simple_function().
  • Also, note that in the line:
simple_function = myFunction(simple_function)
click below button to copy the code. By Python tutorial team
  • The decorator(myFunction) is rebinding function name to decorator result.
  • So, when the simple_function is later called, it's actually calling the object returned by the decorator.
  • We've seen the rebinding when we define a static method:
>>> class A:
...    def s(x):
...       print(x)
...    s = staticmethod(s)
... 
>>> A.s(10)
10
click below button to copy the code. By Python tutorial team
  • The equivalent code using decorator looks like this:
>>> class A:
...    @staticmethod
...    def s(x):
...       print(x)
... 
>>> A.s(10)
10
click below button to copy the code. By Python tutorial team
  • Another example: suppose we have two functions defined this way:
>>> def wrapper(f):
...    return f
... 
>>> def foo():
...    pass
... 
click below button to copy the code. By Python tutorial team
  • Then, the wrapper can be used for rebinding foo() like this:
>>> foo = wrapper(foo)
click below button to copy the code. By Python tutorial team
  • So, it's a decorator:
>>> @wrapper
... def foo():
...    pass
click below button to copy the code. By Python tutorial team
  • With a decorator defined as below:
def decorator(f):
   #process function
   return f
click below button to copy the code. By Python tutorial team
  • it automatically maps the following:
@decorator
def f(arg):
   return arg*arg

f(123)  # output 15129
click below button to copy the code. By Python tutorial team
  • into the equivalent form as shown below:
def f(arg):
   print arg*arg
f = decorator(f)
click below button to copy the code. By Python tutorial team
  • The decorator is a callable object that returns a callable object with the same number of argument as f.
  • So, decoration maps the following line:
f(123)  
click below button to copy the code. By Python tutorial team
  • into
decorator(f)(123)    
click below button to copy the code. By Python tutorial team

Background


Following are important facts about functions in Python that are useful to understand decorator functions.

  1. In Python, we can define a function inside another function.
  2. In Python, a function can be passed as parameter to another function (a function can also return another function).
 python functions

Learn Python - Python tutorial - python functions - Python examples - Python programs

python - Sample - python code :

# A Python program to demonstrate that a function
# can be defined inside another function and a
# function can be passed as parameter.
 
# Adds a welcome message to the string
def messageWithWelcome(str):
 
    # Nested function
    def addWelcome():
        return "Welcome to "
 
    # Return concatenation of addWelcome()
    # and str.
    return  addWelcome() + str
 
# To get site name to which welcome is added
def site(site_name):
    return site_name
 
print messageWithWelcome(site("Wikitechy"))

Output:

Welcome to Wikitechy

Function Decorator

decorator

A decorator is a function that takes a function as its only parameter and returns a function. This is helpful to “wrap” functionality with the same code over and over again. For example, above code can be re-written as following.

decorator examples

We use @func_name to specify a decorator to be applied on another function.

creating decorator

python - Sample - python code :

# Adds a welcome message to the string
# returned by fun(). Takes fun() as
# parameter and returns welcome().
def decorate_message(fun):
 
    # Nested function
    def addWelcome(site_name):
        return "Welcome to " + fun(site_name)
 
    # Decorator returns a function
    return addWelcome
 
@decorate_message
def site(site_name):
    return site_name;
 
# Driver code
 
# This call is equivalent to call to
# decorate_message() with function
# site("Wikitechy") as parameter
print site("Wikitechy")

Output:

Welcome to Wikitechy
simple decorator

Decorators can also be useful to attach data (or add attribute) to functions.

python - Sample - python code :

# A Python example to demonstrate that
# decorators can be useful attach data
 
# A decorator function to attach
# data to func
def attach_data(func):
       func.data = 3
       return func
 
@attach_data
def add (x, y):
       return x + y
 
# Driver code
 
# This call is equivalent to attach_data()
# with add() as parameter
print(add(2, 3))
 
print(add.data)

Output:

5
3

‘add()’ returns sum of x and y passed as arguments but it is wrapped by a decorator function, calling add(2, 3) would simply give sum of two numbers but when we call add.data then ‘add’ function is passed into then decorator function ‘attach_data’ as argument and this function returns ‘add’ function with an attribute ‘data’ that is set to 3 and hence prints it.

Python decorators are a powerful tool to remove redundancy.


Wikitechy tutorial site provides you all the learn python , learn to program in python , python coding class , learn python programming language online , learn python coding , learn how to code python , free python course online , python training online free , python book , python developer , python online course free

Related Searches to Function Decorators in Python | Introduction