日志记录、性能测试等场合。

想象一下这个很常见的场景,你写了一个方法只提供给以登陆的用户访问(事实上我也是通过django的@login_required才了解到@修饰符的),你可以写以下代码:


这当然没什么问题,但是你又写了一个方法B,也要求只有登录用户可以访问,于是有写了以下代码:

1. def A():  
2. if user.is_login():  
3.         do something  
4. else:  
5. pass



1. def B():  
2. if user.is_login():  
3.         do something  
4. else:  
5. pass


问题出来了,你在复制粘贴,如果不是两个方法而是一堆方法,你可能就有点受不了啦。当然聪明的你可以想出这个方法:



1. def A():  
2. pass  
3. def B():  
4. pass  
5. def login_required(fn):  
6. def ff():  
7. if user.is_login():  
8.             fn()  
9. else:  
10. pass  
11. return ff  
12.   
13. A = login_required(A)  
14. B = login_required(B)

你可能没有想到,对于这么好用的东西,python优雅的支持,这就是@修饰符 


1. def login_required(fn):  
2. def ff():  
3. if user.is_login():  
4.             fn()  
5. else:  
6. pass  
7. return ff  
8. 
9. @login_required  
10. def A():  
11. pass  
12. @login_required  
13. def B():  
14. pass



在方法A上边写一个@修饰符,调用方法A的时候会调用修饰符后边的方法B,方法B以A方法为参数,而且需要返回一个可调用的对象,这个可调用的对象会使用A方法提供的参数执行。看这个例子:



1. #!/usr/bin/env python  
2.   
3. def a(fn):  
4. print 'a'  
5. def d(st):  
6. print st+'d'  
7. return d  
8.   
9. def b(fn):  
10. print 'b'  
11. return fn  
12. 
13. @a  
14. @b  
15. def c(st):  
16. print st  
17.       
18. c('c')


输出结果:bacd

我们调用c('c')的时候会先调用b(c),b(c)打印字符"b"然后返回c,然后再调用a(c),a(c)打印字符"a",然后返回方法d,然后再执行d('c'),打印cd。