一、类的方法的装饰
普通的函数可以用装饰器进行装饰,类的方法也可以用装饰器进行装饰。例如:
def zhshi01(fff):
def baibei(self,x):return (fff(x) +5)*1000
return baibei
class c01():
def fun01(self,x):return 3*x-7
@ zhshi01
def fun02(x):return 3*x-7
obj01=c01()
print(obj01.fun01(8),obj01.fun02(8)) # 17 22000
因为装饰内的闭包函数将真正接受实参,所以,在设计用于装饰类的方法的装饰器时,装饰器内的闭包函数必须要有一个形参。在实际调用时,系统将自动把类对象作为实参赋给闭包函数的第一个形参。
二、类装饰器
装饰的本质就是,给被装饰的东东在不改变其内在结构的前提下添加额外的功能,简单地说,就是把装饰器的功能附加到被装饰者身上。
类装饰器,就是专门用于装饰类的装饰器,通过装饰以扩充被装饰类的数据成员和方法。装饰类的装饰函数以类为参数,返回的也是类。例如:
def f01(self,x,y):return x*y
def zhshi02(cls):
def baibei(x,y):cls.c = 100; cls.f=f01;return cls(x,y)
return baibei
@ zhshi02 # 类通过装饰,能增加一个数据成员 a、一个方法 f
class c02():
a = 200
def __init__(self,x,y):self.b=(x+y)*self.a
obj02 = c02(7,8)
print(obj02.a,obj02.b,obj02.c,obj02.f(3,50)) # 200 3000 100 150
三、装饰器类
装饰器实际就是一个以其它函数为参数,然后返回一个闭包函数的函数,而在一个类中,如果存在一个__call__()魔法函数,则该类的对象也能像函数一样被调用,也就是说,有__call__()的对象就可以看作一个函数。函数可以用作装饰器,有__call__()的对象也同样可以用作装饰器。
装饰器类,即是可以用作装饰器的类。装饰器类在运行中并不显式地创建一个对象,但实际上是会隐式地创建一个对象,并通过__init__()来接收一个函数,然后通过__call__()来返回一个函数。例如:
class c03():
def __init__(self,fff):self.f=fff;self.a=100
def __call__(self,x,y):return (self.f(x,y) +5)*self.a
@ c03
def fun03(x,y):return x*y
print(fun03(7,8)) # 6100
四、类装饰类
装饰器类可以用作装饰器,装饰除了可以装饰函数也可以装饰类,那么,装饰器类装饰类,即类装饰类,就变得很自然了。例如:
class c04:
def __init__(self,cls):self.c=cls;self.a=100;print('This is c04')
def __call__(self,x,y):self.c.b=(x+y)*self.a; return self.c
@ c04
class c05:
d=200
def __init__(self):print('This is c05')
obj05=c05(8,9)
print(obj05.b,obj05.d) # This is c04 1700 200
类被装饰之后,实际创建的对象已经不再是被装饰类的对象,而是装饰器类的对象,所以,创建对象时被装饰类的构造函数不会起作用。