一 简介
Python装饰器(decorator)是一种设计模式,它允许你在不改变函数内部代码的情况下,动态地给函数添加功能。装饰器本质上是一个返回函数的高阶函数(higher-order function)。装饰器的主要作用是修改或扩展函数的行为。
二 基础语法
函数在python中也属于一等对象,意味着函数可以作为一个参数传递给另一个函数
def square(x):
return x*x
def print_running(f,x):
print(f'{f.__name__} is running')
return f(x)
result = print_running(square,2) #square is running
print(result) # 4
装饰器本质也是一个函数,将装饰的函数当作一个参数传递给装饰器并返回一个新的函数,新函数在包含传入函数的同时扩充了其他的功能,调用装饰过的函数即为调用这个返回的新函数
#测量函数运行时间
import time
def decoretor(func):
def wrapper(*args,**kwargs):
start_time = time.time()
print(f'{func.__name__} is running')
result = func(*args,**kwargs)
end_time = time.time()
print(end_time-start_time)
return result
return wrapper
@decoretor
def square(x):
return x*x #square is running 3.7670135498046875e-05
装饰器生成器
根据传入的参数生成不同的装饰器,传入不同的阈值可以测量自行调整阈值,以测量函数运行时间是否超过阈值
import functools
def timer(threshold):
def decorator(func):
@functools.wraps(func)
def wrapper(*args,**kargs):
start_time = time.time()
result = func(*args,**kargs)
end_time = time.time()
if end_time - start_time >= threshold:
print(f'{func.__name__} took longer')
return result
return wrapper
return decorator
@timer(0.2)
def sleep_04():
time.sleep(0.4)
sleep_04() # sleep_04 took longer
三 常见场景
- 日志记录:在函数调用前后记录日志。
- 访问控制:检查用户是否有权限执行某个操作。
- 性能计时:计算函数的执行时间。
- 缓存:将函数的返回值缓存起来,以提高性能。
四 类装饰器
除了函数装饰器,Python 还支持类装饰器。类装饰器通过定义__call__方法,可以像函数一样调用。
class CountCalls:
def __init__(self, func):
self.func = func
self.num_calls = 0
def __call__(self, *args, **kwargs):
self.num_calls += 1
print(f"Call {self.num_calls} of {self.func.__name__}")
return self.func(*args, **kwargs)
@CountCalls
def say_hello():
print("Hello!")
say_hello() # Call 1 of say_hello Hello!
say_hello() # Call 2 of say_hello Hello!