zoukankan      html  css  js  c++  java
  • python装饰器

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

    2. 装饰器语法

    (1)无参数装饰器

    [python] view plaincopy
     
    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 plaincopy
     
    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 plaincopy
     
    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 plaincopy
     
    1. def synchronized(lock):  
    2.     """锁同步装饰方法 
    3.     !lock必须实现了acquire和release方法 
    4.     """  
    5.     def sync_with_lock(func):  
    6.         def new_func(*args, **kwargs):  
    7.             lock.acquire()  
    8.             try:  
    9.                 return func(*args, **kwargs)  
    10.             finally:  
    11.                 lock.release()  
    12.         new_func.func_name = func.func_name  
    13.         new_func.__doc__ = func.__doc__  
    14.         return new_func  
    15.     return sync_with_lock  
    16. @synchronized(__locker)  
    17. def update(data):  
    18. """更新计划任务"""  
    19.     tasks = self.get_tasks()  
    20.     delete_task = None  
    21.     for task in tasks:  
    22.         if task[PLANTASK.ID] == data[PLANTASK.ID]:  
    23.             tasks.insert(tasks.index(task), data)  
    24.             tasks.remove(task)  
    25.             delete_task = task  
    26.     r, msg = self._refresh(tasks, delete_task)  
    27.     return r, msg, data[PLANTASK.ID]  

    调用时还是updae(data)。

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

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

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

  • 相关阅读:
    OAuth2集成——《跟我学Shiro》
    Spring的servlet context和application context
    Spring MVC中如何指定某个类或方法自适配地响应某个HTTP请求?
    spring security的标签库
    使用 Spring 2.5 基于注解驱动的 Spring MVC
    在数据库历史上最重要的人物简介
    工作流引擎Activiti使用总结
    Activiti初学者教程
    比较Activiti中三种不同的表单及其应用
    Activiti工作流引擎使用
  • 原文地址:https://www.cnblogs.com/sweet521/p/4033451.html
Copyright © 2011-2022 走看看