前言
最近跟着《流畅的Python》和《Python Cookbook》学习,看到装饰器部分,有些头大
倒不是因为概念难以理解,而是书和网上文章中有些地方有些矛盾之处
在简单学习和实践之后,整理出我对装饰器的理解如下
装饰器的定义
在不同语境下,装饰器有不一样的含义,我大致认为有3种定义:
- 一种把另一个对象当参数的对象
- 一种语法糖
- 面对对象设计中的装饰器模式
之所以这里特别指出,是因为在很多文章和书中
把装饰器定义成一个函数,有些更扩展一些,把装饰器定义成一个callable对象
对刚开始学习的读者来说这么解释或许不错,但在使用python的过程中,我们发现装饰器可以是
- 函数
- 类 (例:
classmethod
和property
) - 实例方法 (例:
FLask
类的实例app
的route
方法) - 类方法
如果说方法有__call__
方法,能符合上面callable对象的定义的话
classmethod类和property类可没__call__
方法,所以我认为更准确的定义是我上面总结的前两点
装饰器的作用
广义上说,更优雅地处理对象,相比taget = decorate(target)
,@decorate
可要优雅多了
狭义上说,各种功能:
- 禁止函数运行 (刚想到,写个不return原函数的装饰器去装饰某函数,这个函数不就不运行了嘛,不晓得是否有人会这么干)
- 记录函数的运行状况
- 缓存计算结果
- 检查/修改参数
- 装逼?
- 其他
装饰器的使用注意点
- 使用多个装饰器时的运行顺序;最外围/上面的装饰器最晚生效;特别当装饰器返回一个和原先不同类型的对象(比如
classmethod
)时,更要小心 - 记得用
functools
中的wraps
保留被装饰对象的属性 - 其他(还没想到)