装饰器
1. 装饰器的定义与用法
装饰器是一个返回值为另一个函数的函数,通常使用
@wrapper
语法形式来进行函数变换
装饰器的常见例子包括classmethod()
和staticmethod()
装饰器语法只是一种语法糖
装饰器的作用可以简单理解成在不改变现有函数名称、内容以及其调用方式的基础上,为函数添加额外的功能
以下两个函数定义在语义上完全等价:
python
def f(arg):
pass
f = staticmethod(f)
# 等价于
@staticmethod
def f(arg):
pass
一个函数定义可以被一个或多个装饰器表达式所包装。
多个装饰器会以嵌套方式被应用。 例如以下代码:
python
@f1(arg)
@f2
def func(): pass
# 等价于
def func(): pass
func = f1(arg)(f2(func))
类也可以被装饰:就像装饰函数一样。
类装饰器表达式的求值规则与函数装饰器相同。结果随后会被绑定到类名称。
python
@f1(arg)
@f2
class Foo: pass
# 等价于
class Foo: pass
Foo = f1(arg)(f2(Foo))
2. 自定义装饰器
2.1 普通的装饰器
下面实现一个记录函数运行时间的装饰器:
python
import time
def run_time(func):
"""记录函数运行时间"""
def wrapper(*args, **kwargs):
begin_time = time.time()
func(*args, **kwargs)
end_time = time.time()
print(f'{func.__name__}函数运行时间为:', end_time - begin_time)
return wrapper
@run_time
def test():
print('进入 test 函数')
time.sleep(1)
print('离开 test 函数')
test()
txt
进入 test 函数
离开 test 函数
test函数运行时间为: 1.0015549659729004
2.2 带参数的装饰器
为上面 run_time
装饰器加上一个参数 sleep_second
:额外睡眠一段时间,延长函数运行时间;为后续的性能优化留足空间:
python
import time
def run_time(sleep_second):
"""记录函数运行时间"""
def decorator(func):
def wrapper(*args, **kwargs):
begin_time = time.time()
func(*args, **kwargs)
time.sleep(sleep_second)
end_time = time.time()
print(f'{func.__name__}函数运行时间为:', end_time - begin_time)
return wrapper
return decorator
@run_time(1)
def test():
print('进入 test 函数')
time.sleep(1)
print('离开 test 函数')
test()
执行结果如下:
txt
进入 test 函数
离开 test 函数
test函数运行时间为: 2.0029916763305664