目录:
装饰器可以在不修改原函数的前提下,给原函数增加一些额外的功能,非常优雅。
如下示例: timers 装饰器给原函数 original_func 增加了计算函数运行时间的功能。
import time
from functools import wraps
def timer(func):
@wraps(func) # 关键:保留原函数的元信息(如名称、文档字符串)
def wrapper(*args, **kwargs):
start_time = time.perf_counter()
# 运行原函数
result = func(*args, **kwargs)
end_time = time.perf_counter()
elapsed = end_time - start_time
print(f"函数 '{func.__name__}' 运行耗时: {elapsed:.4f} 秒")
return result
return wrapper
@timer
def original_func():
time.sleep(3)
original_func()
# 输出: 函数 'original_func' 运行耗时: 3.0028 秒
装饰器本身也是一个函数,内部又定义了一个函数 wrapper 并将其返回,原函数在 wrapper 内部会运行,所以开发者可以在原函数运行前或运行后做一些额外操作。
def decorate_name(func):
def wrapper(*args, **kwargs):
print('start....')
# 运行原函数
r = func(*args, **kwargs)
print('end.....')
return r
return wrapper
@decorate_name
def original_func():
print('original_func....')
original_func()
运行后输出如下:
$ python test.py
start....
original_func....
end.....
有的业务场景装饰器还可以接收参数,如下示例 decorate_name 装饰器接收一个数值参数,此时定义装饰器会多一层嵌套。
def decorate_name(n):
def outer_wrapper(func):
def inner_wrapper(*args, **kwargs):
print('装饰器参数 = {}'.format(n))
# 运行原函数
r = func(*args, **kwargs)
return r
return inner_wrapper
return outer_wrapper
@decorate_name(1)
def original_func():
print('original_func....')
original_func()
# 装饰器参数 = 1
# original_func....
from datetime import datetime
def print_func_args(func):
"""
装饰器: 打印方法参数
"""
def wrapper(*args, **kwargs):
print('function params args: {}, kwargs: {}'.format(args, kwargs))
r = func(*args, **kwargs)
return r
return wrapper
def print_func_return(func):
"""
装饰器: 打印方法返回值
"""
def wrapper(*args, **kwargs):
r = func(*args, **kwargs)
print('function return {}'.format(r))
return r
return wrapper
def print_func_time(func):
"""
装饰器: 打印方法执行时间
"""
def wrapper(*args, **kwargs):
start_time = datetime.now()
r = func(*args, **kwargs)
end_time = datetime.now()
time = end_time - start_time
print('function time {}'.format(time))
return r
return wrapper
def print_func_info(func):
"""
装饰器: 打印方法参数、返回值、执行时间
"""
def wrapper(*args, **kwargs):
start_time = datetime.datetime.now()
r = func(*args, **kwargs)
end_time = datetime.datetime.now()
time = end_time - start_time
print('function params args: {}, kwargs: {}'.format(args, kwargs))
print('function return {}'.format(r))
print('function time {}'.format(time))
return wrapper
@print_func_time
@print_func_return
@print_func_args
def add(a, b):
return a + b
add(1, 2)
# 输出:
# function params args: (1, 2), kwargs: {}
# function return 3
# function time 0:00:00.000040
↶ 返回首页 ↶