装饰器 用于减少重复代码,使得代码在编写时更加简洁、灵活
1、装饰器(函数)装饰函数(这个有点绕)
def a(func): def b(*args,**kw): print("this is start") func(*args,**kw) print("end") return return b @a def c(): print("here is the c function")
2、装饰器类装饰函数。类Desc里含有all函数用来装饰类Samp里的one方法。这种方法可以改变被装饰类的属性值。
class Desc(object): def __init__(self): pass def all(self, fun): #此处的self是指向Desc
print("in des") def out(self, *args, **kwargs): #此处的self是指向所装饰的类 self.b = 2 fun(self, *args, **kwargs) #此处的self是指向所装饰的类 return out class Samp(object): des = Desc() # 需要先实例一个类才能使用 def __init__(self): self.a = 'say hi' self.b = 0 @des.all def one(self): print self.a return
sa = Samp()
sa.one()
print sa.b
输出如下:
in des # 此处的输出是在sa = Samp()实例化的时候就已经运行了def all(self, fun)函数里的print("in des"),但并不会运行out()函数,所以,即使后面有很多个sa.one(),也只会输出一次in des。 say hi 2 # self.b的值已经被改变了
3、装饰器(类)装饰 类
class Desc(object): def __init__(self,fun): self.fun = fun def __call__(self,*args,**kwargs): #此处的self是指向Desc本类 print "in des" self.b = 2 # 此处的self是指向Desc本类,所以被装饰类的self.b并没有改变 return self.fun(*args,**kwargs) @Desc class Sampee(object): def __init__(self): self.a = 'say hi' self.b = 0 def one(self): print self.a return def two(self): print self.b return
sa = Sampee() # 此处会先运行Desc的__init__和__call__,再到Sampee的__init__ sa.one() sa.two()
输出如下:
in des say hi 0
装饰器类装饰类,就相当方法装饰方法,__call__函数是在调用类的时候触发的函数,装饰函数的主要内容都写在__call__函数里。在被装饰的类实例化时会先运行装饰类,Desc类中的__call__装饰的就是Sampee类的初始化函数,初始化传入参数,所对应的就是__call__传入的参数。装饰类与Sampee类的方法无关。