装饰器

装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

例子:

def foo():
    print('i am foo')

现在有需求,希望可以记录下函数的执行日志, 于是在代码中添加日志代码:

def foo():
    print('i am foo')
    logging.info('foo is running')

简单装饰器

def use_logging(func):

    def wrapper(*args, **kwargs):
        logging.warn("{}s is running".format(func.__name__))
        return func(*args, **kwargs)
    return wrapper

def bar():
    print('i am bar')

bar = use_logging(bar)
bar()

函数use_logging就是装饰器,它把执行真正业务方法的func包裹在函数里面,看起来像bar被use_logging装饰了。在这个例子中,函数进入和退出时 ,被称为一个横切面(Aspect),这种编程方式被称为面向切面的编程(Aspect-Oriented Programming)。

@符号是装饰器的语法糖,在定义函数的时候使用,避免再一次赋值操作.

def use_logging(func):

    def wrapper(*args, **kwargs):
        logging.warn("{}s is running".format(func.__name__))
        return func(*args)
    return wrapper

@use_logging
def foo():
    print("i am foo")

@use_logging
def bar():
    print("i am bar")

bar()

带参装饰器

装饰器还有更大的灵活性,可以传入参数.

类装饰器

再来看看类装饰器,相比函数装饰器,类装饰器具有灵活度大、高内聚、封装性等优点。使用类装饰器还可以依靠类内部的__call__方法,当使用 @ 形式将装饰器附加到函数上时,就会调用此方法。

class Foo(object):
    def __init__(self, func):
    self._func = func

def __call__(self):
    print ('class decorator runing')
    self._func()
    print ('class decorator ending')

@Foo
def bar():
    print ('bar')

bar()

柯里化

def add(x,y):

    return x + y

def logger(fn):

    def wrapper(*args,**kwargs):

        print('begin')

        x = fn(*args,**kwargs)

        print('end')

        return x

    return wrapper

print(logger(add)(5,y=50))
Copyright © hubhack 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-08-01 11:30:45

results matching ""

    No results matching ""