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('
')
#使用语法糖
@Test
def hello():
print("------hello-------")
hello()
- 其实
@Test
就等价于t = Test(hello)
4. 与普通装饰器类似,也要处理func的“不定参数和返回值自适应”的问题。
待以后遇到实际问题再处理