Python之装饰器
什么是装饰器
在《Fluent Python》里说, A decorator is a callable that takes another function as argument。也就是装饰器就是一个可执行对象,它的参数是一个函数。
1 | @decorate |
相当于
1 | def target(): |
另一个重要的问题是当模块导入时,装饰器就执行了。
编写registration.py
1 | registry = [] |
之后导入模块,可以看到registration.registry的值
1 | >>> import registration |
编写一个装饰器
下面编写一个记录函数执行时间的装饰器,保存到clockdeco.py中
1 | import time |
之后使用这个装饰器
1 | import time |
可以看到结果
1 | **************************************** Calling snooze(123) [0.12405610s] snooze(.123) -> None **************************************** Calling factorial(6) [0.00000191s] factorial(1) -> 1 |
使用内置装饰器
上面编写的clock装饰器存在一个问题是不支持关键字参数,可以使用标准库里的functools.wraps来解决这个问题。
1 | import time |
Python内置了三个常用的装饰器,property,classmethod和staticmethod,
标准库functools里还有两个有趣的装饰器lru_cache和singledispatch。
编写带参数的装饰器
要编写带参数的装饰器,一个解决的办法是编写一个装饰器工厂,然后根据参数不同,返回不同的装饰器。
拿上面的clock装饰器来说,如果要允许传入时间格式来输出不同的日期格式,可以如下编写装饰器工厂, 保存到clockdeco_param.py中
1 | import time |
编写如下测试代码,可以看到不同的时间格式。
1 | import time |
输出结果如下
1 | [0.12581110s] snooze(0.123) -> None |