1. 类装饰器必须接受一个callable对象
- python强调“函数即对象”,说明对象可以当做函数用。即支持 对象名(实参) :背后的原理是为一个对象自定义__call__()方法,对象立即变成 callable对象, 当执行 对象名(实参) 时,自动激发该对象的__call__()
class Test(): def __call__(self): print('call me!')t = Test()t()
2. 类装饰器接收一个callable对象,把这个callable对象进行装饰后,返回一个callable对象
- 类比对象装饰器的定义:函数A作为参数传入函数B,B的内函数把A装饰后,返回一个函数C。
- 现在就是: 把callable对象{重写了
__call__()
的callable对象就是一个函数}作为参数传入类{实际上是传入类的__init__()
方法里}, ,在类的__call__()
里面把这个callable对象装饰后, 返回一个callable对象{即调用这个类的对象}- 这个类即变成装饰器
- 考虑这样一个过程:现在如果new了一个该类的对象Ins, 就会默认执行
__new__()
,__init__()
。然后执行Ins(),就会自动执行__call__()
,即完成了对开始在__init__()
中传入的callable对象的装饰。
3. 分析下生产一个类装饰器的过程:
- 重写类的
__init__()
,传入一个callable对象- 重写这个类的
__call__()
, 在这个函数内对这个callable对象进行装饰- 使用@类名来装饰一个函数。
- 调用此函数。
class Test(object): def __init__(self,func): #传入待装饰的函数func {注意:这个func必须是callable对象} print("the instance of Test is initializing") self.__func = func #把func给私有属性,以保护func def __call__(self): print("func的前置修饰") self.__func() #其实等价于func(),执行func()本身 print("func的后置修饰") #手动模拟类装饰器的工作过程:def world(): print("-----world--------")t = Test(world)t() #开始执行__call__(),即开始执行装饰操作和func()本身了。print('\n')#使用语法糖 @Testdef hello(): print("------hello-------")hello()
- 其实
@Test
就等价于t = Test(hello)
4. 与普通装饰器类似,也要处理func的“不定参数和返回值自适应”的问题。
待以后遇到实际问题再处理