# ### 装饰器 """ 定义:装饰器用于拓展原来函数功能的一种语法,返回新函数替换旧函数 优点:在不更改原函数代码的前提下 给函数拓展新的功能 语法:@ """ # 1.装饰器的原型 def kuozhan(func): def newfunc(): print("厕所前,蓬头垢面") func() print("厕所后,容光焕发") return newfunc def func(): print("我是高富帅") func = kuozhan(func) # func = newfunc func() # newfunc() # 2.装饰器@符语法 """ @符有两个作用: (1)把@符下面的函数当成一个参数传递给装饰器 (2)装饰器经过装饰之后,把新函数返回,让新函数去替换旧函数 (在不改变原有代码的前提下,扩展新功能) """ def kuozhan(func): def newfunc(): print("厕所前,衣衫褴褛") func() print("厕所后,光鲜亮丽") return newfunc @kuozhan def func(): print("我是白富美") func() # 3.装饰器的嵌套 def kuozhan1(func): def newfunc(): print("厕所前,饥肠辘辘1") func() print("厕所后,酒足饭饱2") return newfunc def kuozhan2(func): def newfunc(): print("厕所前,洗洗手3") func() print("厕所后,簌簌口4") return newfunc @kuozhan2 @kuozhan1 def func(): print("我是个屌丝5") func() print("<===============>") # 4.用装饰器装饰带有参数的函数 """原函数几个参数,装饰之后就是几个参数,不要乱改""" def kuozhan(func): def newfunc(who,where): print("厕所前,饥饿难耐") func(who,where) print("厕所后,满口雌黄,口吐芬芳") return newfunc @kuozhan def func(who,where): print("{}在{}解手".format(who,where)) func("黄乐锡","鸟窝") print("<===============>") # 5.用装饰器装饰带有参数返回值的函数 def kuozhan(func): # 在定义处 * 和 ** 用来收集,打包 def newfunc(*args,**kwargs): print("厕所前,萎靡不振") # 在调用处 * 和 ** 用来打散,解包 res = func(*args,**kwargs) print("厕所后,兽性大发") return res return newfunc @kuozhan def func(*args,**kwargs): dic = {"zyl":"邹永灵","zl":"张龙","zzl":"众赞林"} strvar = "" for i in args: strvar += i + " " print("解手地点:" + strvar) # "谁" 留下了"什么" """ # 方法一 lst = [] for k,v in kwargs.items(): if k in dic: res = dic[k] + "留下了" + v + "黄金" lst.append(res) """ # 方法二 lst = [dic[k] + "留下了" + v + "黄金" for k,v in kwargs.items() if k in dic] return lst res = func("电影院","水里",zyl="15克",zl="15斤",zzl="15吨",ww="没有") print(res) # 6.用类装饰器装饰原函数 class Kuozhan(): # 原函数被func这个形参接收到了 def __call__(self,func): # 调用一下kuozhan2函数 , 返回newfunc新函数 return self.kuozhan2(func) def kuozhan1(func): def newfunc(): print("厕所前,干净整齐") func() print("厕所后,臭气熏天") return newfunc def kuozhan2(self,func): def newfunc(): print("厕所前,人模狗样") func() print("厕所后,原形毕露") return newfunc # 方法一 @Kuozhan.kuozhan1 def func(): print("厕所进行时 ... ") func() print("<=======>") # 方法二 @Kuozhan() # @obj => obj(func) 把对象当成函数使用,触发__call__方法 def func(): print("厕所进行时 ... ") # func = newfunc func() # newfunc() # 7.用带有参数的装饰器装饰原函数 """为了保留参数n存储的值,在套一层函数形成闭包,延长n的生命周期,供内函数使用""" def outer(n): def kuozhan(func): def newfunc1(self): print("厕所前,饥肠辘辘1") func(self) print("厕所后,呕吐不止1") def newfunc2(self): print("厕所前,饥肠辘辘2") func(self) print("厕所后,呕吐不止2") if n == 1: return newfunc1 elif n == 2: return newfunc2 elif n == 3: return 5488 return kuozhan print("<========================>") class MyClass(): @outer(1) # @kuozhan def func1(self): print("向前一小步,文明一大步") @outer(2) def func2(self): print("来也冲冲,去也冲冲") @outer(3) def func3(self): print("绿巨人觉得还行") obj = MyClass() # 扩展原函数新功能 obj.func1() # newfunc1() obj.func2() # newfunc2() # 把方法变成属性 print(obj.func3) # func3 = 5488 # 8.用带有参数的类装饰器装饰原函数 """ 如果参数是1,就为当前这个类添加成员属性和方法 如果参数是2,就把当前这个类中的run方法变成属性 """ class Kuozhan(): ad = "贵族茅厕,欢迎您来,欢迎您再来" def __init__(self,num): self.num = num def money(self): print("贵族茅厕,每小时收费100,包月1450.") def __call__(self,cls): if self.num == 1: return self.kuozhan1(cls) elif self.num == 2: return self.kuozhan2(cls) def kuozhan1(self,cls): def newfunc(): self.addpty(cls) # 返回的是对象 return cls() return newfunc def addpty(self,cls): # 为当前cls添加成员属性 cls.ad = Kuozhan.ad # 为当前cls添加成员方法 cls.money = Kuozhan.money def kuozhan2(self,cls): def newfunc(): return self.updatepty(cls) # cls() return newfunc def updatepty(self,cls): if "run" in cls.__dict__: cls.run = cls.run() # "亢龙有悔" return cls() """ @obj => obj(MyClass) => newfunc @符发动第二次技能,将新函数替换旧函数 MyClass = newfunc obj = MyClass() <=> newfunc() <=> cls() obj.ad obj.money() obj.run = "亢龙有悔" """ # 功能一 @Kuozhan(1) # @obj => obj(MyClass) 把对象当成函数使用了,会触发__call__魔术方法 class MyClass(): def run(): return "亢龙有悔" obj = MyClass() print(obj.ad) obj.money() # 功能二 @Kuozhan(2) class MyClass(): def run(): return "亢龙有悔" obj = MyClass() print(obj.run) # 扩展1 """ # 把类当成一个参数传递到函数中,形成一个独立的副本; class MyClass(): a = 1 def func(cls): cls.ad = 2 return cls() obj = func(MyClass) MyClass = 1 print(MyClass) print(obj.ad) # 可以在函数内部创建类,但是作用域只限定在函数的内部,外部不可见; def func(): class C(): cbb = 10 obj = C() return obj obj = func() print(obj.cbb) """