【Python】--装饰器
装饰器(Decorator)本质上是一个返回函数的函数
主要作用是:在不修改原函数代码的前提下,给函数增加额外的功能
比如:增加业务,日志记录、权限验证、执行时间统计、缓存等场景
@my_decorator
def func():pass# 等价于:
def func():pass
func = my_decorator(func)
1、闭包
def outer(x):def inner(y):return x + yreturn inneradd5 = outer(5)
print(add5(3)) # 输出 8
闭包(Closure)
指一个函数定义在另一个函数内部,并且这个内部函数引用了外部函数的变量。即使外部函数已经返回了,内部函数依然**“记住”**并可以访问这些变量
就如这里的x
功能
-
保存函数执行时的“上下文”;
-
用于延迟计算或构造回调函数;
-
实现数据隐藏(类似于面向对象中的私有变量);
-
替代某些简单场景中的类。
2、装饰器基础
装饰器本质上就是闭包的一种应用,用于在不修改函数源代码的情况下增强函数功能
def decorator(func):def wrapper(*args, **kwargs):start_time = time.time()result = func(*args, **kwargs)stop_time = time.time()print(f'running_time is {stop_time - start_time}')return resultreturn wrapper@decorator # double=decorator(double)
def double(x):time.sleep(1) # 模拟耗时return x*2
double(10)
这里在原本的基础上增加了(统计函数执行时间)功能
3、保留函数元数据
使用装饰器后
装饰器会覆盖原函数的元数据
使用functools.wraps
装饰内层函数可保留原函数元数据
import functools
import time# 装饰器outer
def decorator(func):@functools.wraps(func)def wrapper(*args, **kwargs):'''这里是wrapper的注释'''start_time = time.time()result = func(*args, **kwargs)stop_time = time.time()print(f'running_time is {stop_time - start_time}')return resultreturn wrapper
@decorator # double=decorator(double)
def double(x):'''这里是doubled的注释'''time.sleep(1) # 模拟耗时return x*2
double(10)
print(double.__name__)
print(double.__doc__)
4、带参数的装饰器
需要使用三层函数来实现。最外层函数接收装饰器参数,中间层函数接收原函数,最内层函数完成对原函数的调用以及附加功能。
def timer(time_consume):def decorator(func):@functools.wraps(func)def wrapper(*args, **kwargs):start_time = time.time()result = func(*args, **kwargs)stop_time = time.time()if (stop_time - start_time>time_consume):print(f'running is {stop_time - start_time}')print(f'{func.__name__} is longer')return resultreturn wrapperreturn decorator
@timer(0.8) # double=timer(0.8)(double)
def double(x):time.sleep(1) # 模拟耗时return x*2
double(10)