Python decorator

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python decorator相关的知识,希望对你有一定的参考价值。

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

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

 

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

#!python2
#-*- coding:utf-8 -*-



def f():
    print "Call function f"
    
f1=f
f1()

#查看函数对象的名字
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定义处

@log
def f():
    print "Call function f"

f1=f
f.__name__
f1.__name__

#调用函数f不仅会调用f本身还会在其前后打印log
#相当于 f=log(f)

f1()



#下面是接受参数的decorator写法


import functools

def 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=f
f.__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
        
@log
def f():
    print "Call function f"

f1=f
f.__name__
f1.__name__
f1()


@log("sss")
def f():
    print "Call function f"

f1=f
f.__name__
f1.__name__
f1()
#class decorator

class 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_d

def test():
    print "call test func"
    
test()
#装饰器顺序

@a
@b
@c

def f():
    
等价于

f=a(b(c(f)))

 

以上是关于Python decorator的主要内容,如果未能解决你的问题,请参考以下文章

python之装饰器(decorator)

15-python-decorators

python--decorator装饰器

python decorator的本质

Python – 装饰器(Decorator)

python 装饰器 Decorator