python decorators

Decorator is a very expressive language feature in python. It helps developers to write cleaner, modular code that is easier to extend and maintain. It also helps implement AOP and decorator pattern in python.

Decorator syntax
To declare a decorator function, we can define a function that takes a another function as argument and returns a function. The usage of decorator is very simple, just add a line begins with '@' symbol and the name of the decorator before the function to be decorated.

 1 def  decorator(func):
 2      def  new_func():
 3          print  "decorator message"
 4         func()
 5      return new_func
 6
 7 @ decorator
 8 def  foo():
 9      print  "hello world"
10
11 foo()

The effect is when we call foo function, besides print "hello world" message, the message "decorator message" is also printed. That is, the decorator function extends foo function's behavior.
The code above is equivalent to:
 

 1 def  decorator(func):
 2      def  new_func():
 3          print  "decorator message"
 4         func()
 5      return new_func
 6
 7 def  foo():
 8      print  "hello world"
 9
10 foo = decorator(foo)
11 foo()

Decorators can also accept arguments, as long as it returns a decorator function that takes a function as argument.
 1 def  decorator_with_arg(arg):
 2      def  decorator(func):
 3          def  new_func():
 4              print arg
 5             func()
 6          return new_func
 7      return decorator
 8
 9 @ decorator_with_arg( "arg for decorator")
10 def  foo():
11      print  "hello world"
12
13 foo()


The example above is equivalent to :

 1 def  decorator_with_arg(arg):
 2      def  decorator(func):
 3          def  new_func():
 4              print arg
 5             func()
 6          return new_func
 7      return decorator
 8
 9 def  foo():
10      print  "hello world"
11
12 foo = decorator_with_arg( "arg for decorator")(foo)
13 foo()
The decorator_with_arg function creates a closure, so that the arg argument can still be used after the decorator_with_arg returned. Since it's possible for a decorator to accept arguments, the decorator's behavior can changed based on the argument passed in. So it's possible to write more flexible code.

A more practical example
Here is a more practical example. We create a tracable decorator which is a debugging utility. It will keep records of the number of times that a function decorated with it is invoked.
 1 trace_log = {}
 2
 3 def  tracable(func):
 4      def  decorated_func(*arg, **kwarg):
 5          if  not trace_log.has_key(func.__name__):
 6             trace_log[func.__name__] = 1
 7          else:
 8             trace_log[func.__name__] += 1
 9         func(*arg, **kwarg)
10
11      return decorated_func
12
13 def  print_trace_log():
14      for key, value in trace_log.items():
15          print  "%s called %d times"%(key, value)
16
17 @ tracable
18 def  foo1():
19      print  "foo1"
20
21 @ tracable
22 def  foo2(arg, kwd= "keyword arg"):
23      print  "foo2"
24      print arg
25      print kwd
26
27 @ tracable
28 def  foo3():
29      print  "foo3"
30
31 foo1()
32 foo1()
33 foo1()
34 foo2( 12)
35 foo2( 13)
36
37 print_trace_log()

If we run the code, it will prints that foo1 function is called three times and foo2 function is called twice.
As the example showed, the code for implementing tracing is separated from business logic code contained within foo1 and foo2. The maintainability of the program is much higher than if the code for tracing is mixed with business logic code.

Summary
We got several benefits from decorator.
First, it helps achieve a better separation of business logic code and auxiliary code.
Second, it helps finding out where the auxiliary is used because decorator employs a very special syntax.
Third, we can extend or change our business logic without having to change existing code. New code can be implemented as a decorator.


References:
Charming Python: Decorators make magic easy
Decorators for Functions and Methods
PythonDecorators
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值