# ### 装饰器: ''' 装饰器:在不改变原有代码的情况下,为该原函数扩展新功能 特征:返回新函数,替换旧函数 语法:@ (语法糖) ''' # (1) 装饰器原型: def kuozhan(func): def newfunc(): print("厕所前,屁滚尿流") func() print("厕所后,站不起来") return newfunc def func(): print("我是个屌丝") # 手动的 把新函数 赋值给 旧函数 func = kuozhan(func) # res = newfunc func() #newfunc() # (2) 装饰器@ print("<=-===>") def kuozhan(func): def newfunc(): print("厕所前,风流倜傥") func() print("厕所后,面黄肌瘦") return newfunc @kuozhan def func(): print("我是一个高富川") ''' 第一步: 先把下面的func当成参数传递给kuozhan 第二部:把返回的新函数重新赋值给func * 谁跟在@ 这个装饰器的下面,就会自动把谁当成参数传递 func = kuozhan(func) ''' 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() # 3 1 5 2 4 # (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("马军强","鸟窝") # (5) 带有参数返回值的装饰器 '''通过装饰器改造之后,原函数返回什么,新函数返回什么''' def kuozhan(func): def newfunc(*args,**kwargs): print("厕所前,萎靡不振") res = func(*args,**kwargs) #"电影院","游泳池",jzn="15克",ys="15碗",hw="15斤",sc="15吨" print("厕所后,兽性大发") return res return newfunc @kuozhan def func(*args,**kwargs): print(args) for i in args: print("茅厕的地点在:",i) # print(kwargs) dic = {'jzn':"境泽年","ys":"易思","hw":"黄文","sc":"舒畅"} ''' lst = [] for k,v in kwargs.items(): # 如果k在dic这个字典里,说明这个字典存在这个键,然后我就通过键取值 if k in dic: lst.append("{} 留下了黄金 {}".format(dic[k],v)) ''' lst = ["{} 留下了黄金 {}".format(dic[k],v) for k,v in kwargs.items() if k in dic ] return lst res = func("电影院","游泳池",jzn="15克",ys="15碗",hw="15斤",sc="15吨") print("<112233>") print(res) """ * 和 ** 的魔术用法(函数的调用处) def func(a,b,c): print(a,b,c) func(*[1,2,3]) def func(a=1,b=2,c=3,*,d=4): print(a,b,c) func(**{"a":3,"b":4,"c":5,"d":6})#func(a=3,b=4,c=5,d=6) """ # (6) 用类装饰器修饰原函数 class MyClass(): def __call__(self,func): 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 # 方法一 """ @MyClass.kuozhan1 def func(): print("厕所进行时... ... ") func() """ # 方法二 @MyClass() #@obj => obj(func) def func(): print("厕所进行时... ... ") func() ''' 先把@符号右边的值算出来,在通过@符号把下面的函数当成参数进行传递 @MyClass() 就相当于 @obj 把func当成参数传递给obj => obj(func) obj当成一个函数在进行调用,自动触发__call__魔术方法 return newfunc func = newfunc func() 就相当于 newfunc() ''' # (7) 带有参数的函数装饰器 def outer(num): def kuozhan(func): def newfunc1(self): print("厕所前,老实巴交") func(self) print("厕所后,长牙舞爪") def newfunc2(self): print("厕所前,衣冠楚楚") func(self) print("厕所前,衣冠禽兽") if num == 1: return newfunc1 elif num == 2: return newfunc2 elif num == 3: return "今天天气好晴朗哦" return kuozhan class MyClass(): @outer(1) def func1(self): print("向前一小步") @outer(2) def func2(self): print("文明一大步") @outer(3) def func3(self): print("来也冲冲,去也冲冲") print("<===>") obj = MyClass() obj.func1() print("<===>") obj.func2() print("<===>") print(obj.func3) ''' outer(1) => 返回 kuozhan 函数 @kuozhan func1 @符号开始发挥作用 把func1当成参数进行传递,传给kuozhan中的func进行接收 根据num 这个值进行判断 , 返回newfunc1 obj.func1 = newfunc1 obj.func1() <===> newfunc1() @outer(2) => 返回 kuozhan 函数 @kuozhan func3 @符号开始发挥作用 把func3当成参数进行传递,传给kuozhan中的func进行接收 obj.func3 = "今天天气好晴朗哦" print(该值) [因为函数名可以作为变量使用.] ''' # (8) 带有参数的类装饰器 """ 如果传递的参数是1,我就为该类,添加成员属性和方法 如果传递的参数是2,我就把该类当中的run方法变成属性 """ class Kuozhan(): ad = "贵族茅厕,欢迎您来,欢迎您在来" def __init__(self,num): self.num = num def __call__(self,cls): if self.num == 1: return self.kuozhan1(cls) #newfunc 返回 elif self.num == 2: return self.kuozhan2(cls) def money(self): print("贵族茅厕收费标准,每小时10元,包月1400") def kuozhan1(self,cls): def newfunc(): # 添加成员属性 cls.ad = Kuozhan.ad # 添加成员方法 cls.money = Kuozhan.money return cls() return newfunc def kuozhan2(self,cls): def newfunc(): # 先来判断run方法是否在cls当中 if "run" in cls.__dict__: #调用一个类中得run方法拿到返回值"亢龙有悔" res = cls.run() #成员属性run 从方法变成属性,值替换了 cls.run = res # 把"亢龙有悔"进行替换赋值给run成员属性 return cls() return newfunc @Kuozhan(1) #@obj => obj(MyClass) class MyClass(): def run(): return "亢龙有悔" obj = MyClass() print(obj.ad) obj.money() """ Kuozhan(1) => obj 自动触发init方法,存储num =>self.num = num @obj @符发挥作用把MyClass当成一个参数传递给obj => obj(MyClass) 触发__call__魔术方法,最后将newfunc进行返回 MyClass = newfunc 以前是类 现在是函数 obj = MyClass() <===> newfunc() obj = cls() # cls() 是一个对象 是以前MyClass 这个类的对象 """ @Kuozhan(2) class MyClass(): def run(): return "亢龙有悔" obj = MyClass() print(obj.run) print("<==========================================================>") # 外面全局的abc 与 函数内部局部的abc 两者不发生冲突,彼此独立 class abc(): a =19 def func(cls): cls.b = 20 return cls obj2 = func(abc) print(abc().a) abc = 99988777 print(abc) print(obj2.b) print(obj2.a)