蓝鲸python第三题

弄明白了python中的嵌套函数(也就是所谓的闭合函数)之后,再想搞懂python装饰器就简单多了。 

如果要简单地说,python装饰器不过就是一个针对嵌套函数的语法糖 

它的作用就是在函数调用方法不变的情况下,把此函数包装成另一个函数来使用  



一、首先来大致了解下嵌套函数:  

被嵌套与一层函数中的二层函数可以记录上上一层函数作用域中的变量 

举例: 
Python代码   收藏代码
  1. def foo(a):  
  2.     def subfoo(b):  
  3.         return(b + a)  
  4.     return(subfoo)  
  5.   
  6. f = foo('content'#由于foo返回的是subfoo,所以f是对subfoo的引用  
  7. f('sub_'#因为subfoo记录了foo的参数变量'content',所以返回值为'sub_content'  




二、嵌套函数和它的变种(装饰器)  

以下两端代码,作用是相同的,前一个是大姑娘,后一个是女扮男装后的大姑娘 
Python代码   收藏代码
  1. def action(x):  
  2.     return(x)  
  3.   
  4. def action_pro(n):  
  5.     def warpper(x):  
  6.         return(n(x) * x)  
  7.     return(warpper)  
  8.   
  9. action = action_pro(action) #第一个action为自定义的伪装变量,第二个action为上边定义的action函数  
  10. action(3#此函数实际为warpper(3),返回值为9  


总体说起来,装饰器其实也就是一个函数,一个用来包装函数的函数,返回一个修改之后的函数对象,将其重新赋值原来的标识符,并永久丧失对原始函数对象的访问。

三. 装饰器语法

(1)无参数装饰器

[python]  view plain  copy
  1. def deco(func):  
  2.     print func  
  3.     return func  
  4. @deco  
  5. def foo():pass  
  6. foo()  

第一个函数deco是装饰函数,它的参数就是被装饰的函数对象。我们可以在deco函数内对传入的函数对象做一番“装饰”,然后返回这个对象(记住一定要返回 ,不然外面调用foo的地方将会无函数可用。实际上此时foo=deco(foo))

 

我写了个小例子,检查函数有没有说明文档:

[python]  view plain  copy
  1. def deco_functionNeedDoc(func):  
  2.     if func.__doc__ == None :  
  3.         print func, "has no __doc__, it's a bad habit."  
  4.     else:  
  5.         print func, ':', func.__doc__, '.'  
  6.     return func  
  7. @deco_functionNeedDoc  
  8. def f():  
  9.     print 'f() Do something'  
  10. @deco_functionNeedDoc  
  11. def g():  
  12.     'I have a __doc__'  
  13.     print 'g() Do something'  
  14. f()  
  15. g()  

 

(2)有参数装饰器

[cpp]  view plain  copy
  1. def decomaker(arg):  
  2.     '通常对arg会有一定的要求'  
  3.     """由于有参数的decorator函数在调用时只会使用应用时的参数  
  4.        而不接收被装饰的函数做为参数,所以必须在其内部再创建  
  5.        一个函数  
  6.     """  
  7.     def newDeco(func):    #定义一个新的decorator函数  
  8.         print func, arg  
  9.         return func  
  10.     return newDeco  
  11. @decomaker(deco_args)  
  12. def foo():pass  
  13. foo()  

第一个函数decomaker是装饰函数,它的参数是用来加强“加强装饰”的。由于此函数并非被装饰的函数对象,所以在内部必须至少创建一个接受被装饰函数的函数,然后返回这个对象(实际上此时foo=decomaker(arg)(foo))

 

同时还可以将多个装饰器组合 使用:

[python]  view plain  copy
  1. @synchronized(__locker)  
  2. @deco_functionNeedDoc  
  3. def f():  
  4.     print 'f() Do something'  


也就是说。装饰器可以让函数轻装上阵,更重要的是将函数的约束放置于接口处,使意图更加明了,同时又不增加调用者的负担。


学了这个有什么用呢?
装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

下面是参考资料:

1. Python装饰器学习 http://blog.csdn.net/thy38/article/details/4471421

2. Python装饰器与面向切面编程 http://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html

3. Python装饰器的理解 http://apps.hi.baidu.com/share/detail/17572338


你可能感兴趣的:(蓝鲸python第三题)