ChuannBlog

3.3 装饰器

函数装饰器

import time
# 最简单的装饰器
def timer1(func):
    def inner():
        start = time.time()
        func()
        end = time.time()
        print(end - start)
    return inner


def fun():
    s = 0
    for i in range(10000000):
        s += i
    print(s)

fun = timer1(fun)
fun()

理解:装饰器可以不改变对原函数的调用方式,而对在原函数的基础上完成一些附加的事情。

装饰器的本质:闭包函数
功能: 在不改变源代码调用方式的情况下,在这个函数前后加上扩展功能
装饰器契合设计模式的一个原则:
开放封闭原则:
对拓展是开放的,对修改是封闭的。

装饰器的固定结构

def wrapper(func):
    def inner():
        """调用前的扩展功能"""
        ret = func()
        """调用后的扩展功能"""
        return ret
    return inner
@wrapper
def fun():
    pass

带参数的装饰器

带参数的装饰器就是使用两层闭包函数,利用最外层的函数接收参数用于控制装饰器的使用。

FLAG = True
def outer(flag):
    def wrapper(func):
        def inner(*args, **kwargs):
            if flag:
                """函数执行前增加的功能"""
                ret = func(*args, **kwargs)
                """函数执行后增加的功能"""
            else:
                ret = func(*args, **kwargs)
            return ret
        return inner
    return wrapper
@outer(FLAG)
def fun():
    pass

装饰器嵌套

多个装饰器修饰一个函数。

def decorator(func):
    def inner(*args, **kwargs):
        print('decorator: before')
        ret = func(*args, **kwargs)
        print('decorator: after')
        return ret
    return inner
def wrapper(func):
    def inner(*args, **kwargs):
        print('wrapper: before')
        ret = func(*args, **kwargs)
        print('wrapper: after')
        return ret
    return inner
@decorator  # fff = decorator(fff)
@wrapper    # fff = wrapper(fff)
def fff():
    pass

被装饰函数的元信息

from functools import wraps

def decorator(func):
    @wraps
    def inner(*args, **kwargs):
        ret = func(*args, **kwargs)
        return ret
    return inner