首页 > 代码库 > Python decorator

Python decorator

在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)

本质上,decorator就是一个返回函数的高阶函数,它可以让函数在不变动任何代码的前提下增加额外功能。装饰器的返回值也是函数。它经常用于:插入日志,性能测试,事务处理,缓存,权限校验等场景。有了装饰器我们就可以抽离出大量与函数功能本身无关的代码并继续重用。概括的讲,装饰器就是为已经存在的对象添加额外的功能。

 

下面的例子是在调用函数f前后增加打印日志的功能

#!python2#-*- coding:utf-8 -*-def f():    print "Call function f"    f1=ff1()#查看函数对象的名字f.__name__f1.__name__#导入functools模块#因为经过装饰的函数它们的__name__变成了decorator里面的函数名字,对于#这个例子就是write_ahead#为了把原始函数名字等属性复制到write_ahead中我们使用@functools.wraps(func)#这样就可以避免类似write_ahead.__name__ = func.__name__的代码import functools#定义一个decorator,接受函数f为参数def log(func):    @functools.wraps(func)    def write_ahead(*args,**kw):        print "Will Call %s" % f.__name__        func(*args,**kw)        print "After call func:"            return write_ahead#用@把decorator置于函数f定义处@logdef f():    print "Call function f"f1=ff.__name__f1.__name__#调用函数f不仅会调用f本身还会在其前后打印log#相当于 f=log(f)f1()#下面是接受参数的decorator写法import functoolsdef log(text):    def decorator(func):        @functools.wraps(func)        def write_ahead(*args,**kw):            print "Will Call %s with %s" % (f.__name__,text)            func(*args,**kw)            print "After call func:"        return write_ahead    return decorator@log("sss")def f():    print "Call function f"f1=ff.__name__f1.__name__f1()#把以上俩种整合def log(obj):        if isinstance(obj,str):                text=obj                def decorator(func):            @functools.wraps(func)            def write_ahead(*args,**kw):                print "Will Call %s with %s" % (f.__name__,text)                func(*args,**kw)                print "After call func:"            return write_ahead        return decorator        else:                func=obj        @functools.wraps(func)        def write_ahead(*args,**kw):            print "Will Call %s" % f.__name__            func(*args,**kw)            print "After call func:"        return write_ahead        @logdef f():    print "Call function f"f1=ff.__name__f1.__name__f1()@log("sss")def f():    print "Call function f"f1=ff.__name__f1.__name__f1()
#class decoratorclass c_d(object):    def __init__(self,func):        self._func=func            def __call__(self):        print "class decorator is running"        self._func()        print "class decorator is ending"        @c_ddef test():    print "call test func"    test()
#装饰器顺序@a@b@cdef f():    等价于f=a(b(c(f)))

 

Python decorator