装饰器

1.装饰器的作用

在不改变原函数代码和调用方式的基础上,为它增加新功能

2.装饰器原理

import time

def add(a, b):
    time.sleep(1)
    return a + b

1.需求:统计add的运行时间

start_time = time.time()
add(3,4)
end_time = time.time()
print('运行时间是:',end_time-start_time)

2.需求:写一个通用的,以后只要统计任意函数运行时间,都使用通用的

def outer(func):
    start_time = time.time()
    func(3,4)
    end_time = time.time()
    print('运行时间是:', end_time - start_time)
outer(add)

虽然能实现需求,但是改变了调用方式,不行
--->优化

def outer(func):
    def inner(a,b):
        start_time = time.time()
        res = func(a,b)
        end_time = time.time()
        print('运行时间是:', end_time - start_time)
        return res
    return inner
inner=outer(add)
# 调用inner就是在执行,inner内部包了add函数,inner叫闭包函数,
# 闭包函数:定义在外部,对内部作用域有引用
inner() # 还是改变了调用方式

--->继续优化
3.实现需求,下面这种就是装饰器

def outer(func):
    def inner(a,b):
        start_time = time.time()
        res = func(a,b)
        end_time = time.time()
        print('运行时间是:', end_time - start_time)
        return res
    return inner

add = outer(add)
add(3,4) # 本质调用inner,add 本质就是inner,inner要能接收a,b,并且要有返回结果

4.以后想装饰哪个函数就可以直接使用,按照如下操作,比较麻烦

def ee():
    print('ee')

ee = outer(ee)
ee()

5.语法糖,以后只要按如下方式编写代码,就能实现上诉功能

@outer  # 等同于ee = outer(ee) 语法糖会把被装饰器的函数ee,当做参数,传入outer,并且把outer的执行结果,返回赋值给ee
def ee():
    print('ee')
ee()

以后ee其实已经不是ee了,是inner了,执行ee本质在执行inner

3.装饰器模板

def outer(func):
    def inner(*args,**kwargs):
        # 被装饰器函数,执行之前做的
        start_time = time.time()
        res = func(*args,**kwargs)
        end_time = time.time()
        # 被装饰器函数,执行之后做的
        print('运行时间是:',end_time-start_time)
        return res

    return inner

@outer
def add(a, b):
    time.sleep(2)
    return a + b
add(1,2)
posted @ 2023-12-20 20:42  瓜瓜不甜  阅读(9)  评论(0编辑  收藏  举报