python 装饰器学习

最简单的装饰器

本质上,decorator就是一个返回函数的高阶函数。所以,我们要定义一个能打印日志的decorator,可以定义如下:

def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

典型的例子

廖雪峰的课程里的习题:在函数执行之后,打印出执行的时间

import time
import functools

def metric(fn):
    @functools.wraps(fn)
    def wrapper(*args, **kw):
        start = time.time()
        ret = fn(*args, **kw)
        end = time.time()
        print('%s executed in %s ms' % (fn.__name__, (end - start) * 1000))
        return ret
    return wrapper

# 测试
@metric
def fast(x, y):
    time.sleep(0.0012)
    return x + y;

@metric
def slow(x, y, z):
    time.sleep(0.1234)
    return x * y * z;

f = fast(11, 22)
s = slow(11, 22, 33)
if f != 33:
    print('测试失败!')
elif s != 7986:
    print('测试失败!')

带参数的装饰器

如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,写出来会更复杂。比如,要自定义log的文本:

import time

def log(text):
    def decorator(func):
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator


@log("calling: ")
def fast(x, y):
    time.sleep(0.0012)
    return x + y;

fast(1, 2)

装饰器的用处

有一个概念叫【面向切面编程】,一个最典型的例子就是需要在一系列函数运行时,增加一条日志。如果把加日志的代码直接放到目标函数里,工作量大,而且后期不好维护。使用装饰器开源很方便的

你可能感兴趣的:(python 装饰器学习)