02-装饰器
1. 装饰器的定义与用法
装饰器是一个返回值为另一个函数的函数,通常使用 @wrapper
语法形式来进行函数变换
装饰器的常见例子包括 classmethod()
和 staticmethod()
装饰器语法只是一种语法糖
装饰器的作用可以简单理解成在不改变现有函数名称、内容以及其调用方式的基础上,为函数添加额外的功能
以下两个函数定义在语义上完全等价:
| def f(arg):
pass
f = staticmethod(f)
# 等价于
@staticmethod
def f(arg):
pass
|
一个函数定义可以被一个或多个装饰器表达式所包装。
多个装饰器会以嵌套方式被应用。 例如以下代码:
| @f1(arg)
@f2
def func(): pass
# 等价于
def func(): pass
func = f1(arg)(f2(func))
|
类也可以被装饰:就像装饰函数一样。
类装饰器表达式的求值规则与函数装饰器相同。结果随后会被绑定到类名称。
| @f1(arg)
@f2
class Foo: pass
# 等价于
class Foo: pass
Foo = f1(arg)(f2(Foo))
|
2. 自定义装饰器
2.1 普通的装饰器
下面实现一个记录函数运行时间的装饰器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | 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()
|
| 进入 test 函数
离开 test 函数
test函数运行时间为: 1.0015549659729004
|
2.2 带参数的装饰器
为上面 run_time
装饰器加上一个参数 sleep_second
:额外睡眠一段时间,延长函数运行时间;为后续的性能优化留足空间:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | 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()
|
执行结果如下:
| 进入 test 函数
离开 test 函数
test函数运行时间为: 2.0029916763305664
|
=== 全文完 ===
欢迎加入QQ群:855013471