python之decorator理解


The only constraint on the result of a decorator is that it be callable, so it can
properly replace the decorated function.

decorator唯一限制是它必须是callable的,所以如果class作为decorator必须实现__call__方法使其成为callable的对象,而函数本身就是callable的。

用class做decorator

 1 class my_decorator(object):
2 def __init__(self, f):
3 print("inside my_decorator.__init__()")
4 f() # Prove that function definition has completed
5 def __call__(self):
6 print("inside my_decorator.__call__()")
7 @my_decorator
8 def aFunction():
9 print("inside aFunction()")
10 print("Finished decorating aFunction()")
11 aFunction()

输出:

inside my_decorator.__init__()
inside aFunction()
Finished decorating aFunction()
inside my_decorator.__call__()

如何解释这个输出,关键在于decorator程序的阅读要从程序执行顺序来理解,把decorator当成一次函数调用。

当程序从上至下执行到第7行时,my_decorator开始初始化,它以aFunction作为参数,传入__init__()执行,然后__call__将原函数替换,执行第10行代码,最后调用aFunction,因为这时原函数调用时,调用的是decorator替换后的callable对象,也就是__call__方法,所以执行的实际上是__call__。

函数作为decorator

 1 def entry_exit(f):
2 def new_f():
3 print("Entering", f.__name__)
4 f()
5 print("Exited", f.__name__)
6 return new_f
7
8 @entry_exit
9 def func1():
10 print("inside func1()")
11
12 @entry_exit
13 def func2():
14 print("inside func2()")
15
16 func1()
17 func2()

 

同样,程序执行到第8行,调用entry_exit将func1当参数传入执行,返回new_f替换原函数,对func2同样处理,最后调用func1和func2时实际上调用的就是替换了以后的函数。

 

所以decorator从根本上是函数指针的替换,用一个callable的对象替换原来的函数。

 

posted @ 2012-03-05 19:27  babykick  阅读(384)  评论(0编辑  收藏  举报