装饰器的本质
Last updated
Last updated
装饰器(不带参数的装饰器)从实现上看,就是一个“输入和输出都是函数对象”的函数;
带参数的装饰器实际上就是一个返回普通装饰器的函数(可以接受任意参数);
装饰器语法实际上就是以下两种调用形式的语法糖:
类装饰器同理,就是一个“输入和输出都是类对象”的函数,也是类似的语法糖;
装饰器类:具有装饰器功能的类,通过重载 __call__
实现;
示例 1
:装饰器(不带参数)定义装饰器
调用装饰器
等价行为
示例 2
:带参数的装饰器定义装饰器
调用装饰器
等价行为
示例 3
:functools.wraps
的作用在示例 2 中,打印 func.__name__
的结果是 wrapper
;
这是因为经过装饰器后,func
实际上已经指向了另一个函数;
这时可以通过 functools.wraps
装饰器保留原函数的相关属性,用法如下:
functools.wraps
本身也是一个带参数的装饰器;
示例 4
:类装饰器类装饰器就是一个“输入和输出都是类对象”的函数;
定义一个类装饰器:给装饰的类添加一个 printf
函数
调用装饰器
等价行为
示例 5
:装饰器类(不带参数)装饰器类:具有装饰器功能的类,通过重载 __call__
实现;
需要注意的是,该场景下不能使用 functools.wraps
,而应该使用 functools.update_wrapper
,详见示例;
定义装饰器类
调用装饰器类
等价行为
示例 6
:带参数的装饰器类定义装饰器类
调用装饰器类
等价行为