#装饰器:对类或者函数进行功能的扩展  很多需要缩进的没有进行缩进
'''
#第一步:基本函数
def laxi():
print('拉屎')
#调用函数
laxi()
laxi()

print('=======================================')
#第二步:扩展函数的功能(不能修改原函数)
#用于扩展基本函数的函数
#把一个函数(laxi函数)作为一个整体传给另外一个函数(kuozhan函数)
#这个函数(kuozhan函数)用形参func收到了laxi函数,收到之后在中间
#调用laxi函数,并且在前面后面扩展功能
def kuozhan(func):
#扩展功能1
print('拉屎之前')
#调用基本函数
func()
#扩展功能2
print('拉屎之后')
#这里需要有返回值才能传给laxi
#基本函数
def laxi():
print('拉屎')

#扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
print(laxi)

#调用函数
#laxi()

print('=======================================')
#第三步:使用语法糖(就是语法)
#用于扩展基本函数的函数
def kuozhan(func):
#扩展功能1
print('拉屎之前')
#调用基本函数
func()
#扩展功能2
print('拉屎之后')
#这里需要有返回值才能传给laxi
#基本函数
@kuozhan#laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
def laxi():
print('拉屎')
#扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
#laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
print(laxi)

#调用函数
#laxi()

print('=======================================')
#第四步:基本装饰器的实现
#用于扩展基本函数的函数
def kuozhan(func):
#内部函数(扩展之后的laxi函数)
def newlaxi():
#以下三步就是扩展之后的功能,于是我们把这三个哥们做成一个函数
#取名叫做newlaxi
#扩展功能1
print('拉屎之前')
#调用基本函数
func()
#扩展功能2
print('拉屎之后')
#这里需要有返回值才能传给laxi
#添加返回值
#return 12 laxi原来是函数,laxi扩展之后还以函数的形式赋值给laxi
#所以return后面必须是扩展之后的函数
return newlaxi
#基本函数
@kuozhan#laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
def laxi():
print('拉屎')
#扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
#laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
print(laxi)#第四步的目的是为了让打印laxi函数的时候打印一个函数
#而不是像第二步和第三步打印回来的是None
#调用函数
laxi()#laxi就是扩展的内部函数newlaxi函数,就是return返回的值

print('=======================================')
#第五步:带有参数的装饰器
#用于扩展基本函数的函数
def kuozhan(func):
#内部函数(扩展之后的laxi函数)
#5由于调用的时候传了两个参数,未来的laxi函数没有参数接收
#5报错的时候显示newlaxi没有形参接收,但是给了两个实参
#5所以需要添加两个形参接收shui,na
def newlaxi(shui,na):#5调用的杨羊传到了shui,na
#4以下三步就是扩展之后的功能,于是我们把这三个哥们做成一个函数
#4取名叫做newlaxi
#扩展功能1
print('拉屎之前')
#调用基本函数
func(shui,na)#5上面的shui,na传到了这里的shui,na
#扩展功能2
print('拉屎之后')
#4这里需要有返回值才能传给laxi
#添加返回值
#4return 12 laxi原来是函数,laxi扩展之后还以函数的形式赋值给laxi
#4所以return后面必须是扩展之后的函数
return newlaxi
#基本函数
@kuozhan#laxi = kuozhan(laxi) #4laxi就相当于以前的result,用来接收返回值
def laxi(who,where):#5上面的func的shui,na传到了这里的who,where
print(who,'在',where,'拉屎')
print('拉屎')
#扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
#laxi = kuozhan(laxi) #4laxi就相当于以前的result,用来接收返回值
#print(laxi)#4第四步的目的是为了让打印laxi函数的时候打印一个函数
#4而不是像第二步和第三步打印回来的是None
#调用函数
laxi('杨俊','羊圈')#laxi就是扩展的内部函数newlaxi函数,就是return返回的值
laxi('燕飞','鸟窝')

print('=======================================')
def laxi():
print('拉屎')
return '擦屁股'
#扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
#laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
print(laxi)#第四步的目的是为了让打印laxi函数的时候打印一个函数
#而不是像第二步和第三步打印回来的是None
#调用函数
result = laxi()#laxi就是扩展的内部函数newlaxi函数,就是return返回的值
print(result)# 调用和返回值都打印出来了
print('=======================================')
#第五步:带有返回值的装饰器 把第四步复制过来
#用于扩展基本函数的函数
def kuozhan(func):
#内部函数(扩展之后的laxi函数)
def newlaxi():
#以下三步就是扩展之后的功能,于是我们把这三个哥们做成一个函数
#取名叫做newlaxi
#扩展功能1
print('拉屎之前')
#调用基本函数
result1 = func()
#扩展功能2
print('拉屎之后')

#未来的laxi函数没有返回值,所以在最后调用的时候返回值为None
#为newlaxi添加返回值
return result1

#这里需要有返回值才能传给laxi
#添加返回值
#return 12 laxi原来是函数,laxi扩展之后还以函数的形式赋值给laxi
#所以return后面必须是扩展之后的函数
#5装饰器用于返回未来的laxi函数的return
#5而不是newlaxi(laxi)自带的返回值
#5应该在newlaxi函数里面再加一个return
return newlaxi
#基本函数
@kuozhan#laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
def laxi():
print('拉屎')
return '擦屁股'
#扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
#laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
#print(laxi)#第四步的目的是为了让打印laxi函数的时候打印一个函数
#而不是像第二步和第三步打印回来的是None
#调用函数
result = laxi()#laxi就是扩展的内部函数newlaxi函数,就是return返回的值
print('函数的返回值为',result)
print('=======================================')

#第六步:带有收集参数的函数的装饰器
#装饰器函数
def kuozhan(func):
#内部函数(扩展之后的laxi函数)
def newlaxi(*w,**n):
#以下三步就是扩展之后的功能,于是我们把这三个哥们做成一个函数
#取名叫做newlaxi
#扩展功能1
print('拉屎之前')
#调用基本函数
func(*w,**n)
#扩展功能2
print('拉屎之后')
return newlaxi
#基本函数
@kuozhan
def laxi(*who,**nums):
print('参与拉屎的有',who)
print('他们分别拉了多少屎',nums)
print('拉屎')

#调用函数,'
laxi('许钰','王成','秀峰','张波',xy = '15斤',wc = '15吨',xf = '15克',zb = '15升')

print('=======================================')

#第七步:带有参数的装饰器
#两个基本函数用同一个装饰器装饰
def outer(arg):
print(arg)
#这是装饰器的代码
def kuozhan(func):
#print(func) func接收的不再是laxi,而是la,chi
#未来的laxi函数
def newlaxi():
# 扩展功能1
print('拉屎之前')
# 调用基本函数
func()
# 扩展功能2
print('拉屎之后')

def newchifan():
# 扩展功能1
print('吃饭之前')
# 调用基本函数
func()
# 扩展功能2
print('吃饭之后')

if arg == 'la':
return newlaxi
elif arg == 'chi':
return newchifan

#返回装饰器
return kuozhan
#基本函数1
result = outer('la')
@result #@装饰器函数
def laxi():
print('拉屎')

#基本函数2
@outer('chi')
def chifan():
print('吃饭')

#调用基本函数
#laxi()
chifan()

print('==============================================')
#第八步:使用类作为装饰器参数
#装饰器使用的操作类
class Wish:
#祈求方法
def before():
print('拉屎之前')
#还愿方法
def after():
print('拉屎之后')
#装饰器函数
def outer(cls):
def kuozhan(func):
# 未来的laxi函数
def newlaxi():
# 扩展1(类中存在扩展内容)
cls.before()
# 调用基本函数
func()
# 扩展2(类中存在扩展内容)
cls.after()

return newlaxi

return kuozhan

#基本函数
@outer(Wish)#装饰器
def laxi():
print('拉屎')

#调用函数
laxi()

print('==============================================')
#第九步:使用类来作为装饰器

class kuozhan:

#接收装饰器的参数(函数outer)
def __init__(self,arg):
#print(self,arg)arg就是la
self.arg = arg

#制作一个内部函数(真正的装饰器 函数kuozhan)
def __call__(self,func):
#print(self,func)func就是laxi函数
#将func函数存入对象
self.func = func

return self.newlaxi
#在面向对象过程当中不提倡内使用内部函数,要提到前面
#定义称为一个成员方法
def newlaxi(self):
# 扩展功能1
print('拉屎之前')
# 调用基本函数
self.func()
# 扩展功能2
print('拉屎之后')

#基本函数
@kuozhan('la')# laxi = 对象(laxi)
def laxi():
print('拉屎')

#调用函数
laxi()

print('==============================================')
#第十步:装饰器来装饰一个类
def kuozhan(cls):
#print(cls)

#声明一个类并且返回
def newHuman():
# 扩展类的功能1
cls.cloth = '漂亮的小裙子'
# 扩展类的功能2
cls.hat = '亮丽的绿帽子'
#调用类(实例化对象)
obj = cls()
#返回实例化对象
return obj
return newHuman #要让返回的newHuman也能实例化对象
#类(被装饰的类)
@kuozhan #Human = kuozhan(Human) = newHuman
#最后调用的Human()= newHuman()= obj = cls()= 扩展后的Human()
class Human:
#属性
sex = '男'
age = 18

#方法
def liaomei(self):
print('妹子,这块砖头是你掉的吗')

#实例化对象
result = Human()
print(result)
print(result.__dict__)
print(result.cloth)
print(result.hat)
print('===================================================')
#函数的调用
def laxi():
print('拉屎')
return '撒尿'
result = laxi()
print(result)
'''
print('===================================================')
#第十一步:多层装饰器的嵌套

#装饰器1
def kuozhan1(func):
#定义装饰之后的函数
def newlaxi1():
# 扩展功能1
print('1-----拉屎之前')
# 调用基本函数
func()
# 扩展功能2
print('1-----拉屎之后')
return newlaxi1

#装饰器2
def kuozhan2(func):
#定义装饰之后的函数
def newlaxi2():
# 扩展功能1
print('2-----拉屎之前')
# 调用基本函数
func()
# 扩展功能2
print('2-----拉屎之后')
return newlaxi2

#基本函数
@kuozhan2
@kuozhan1
def laxi():
print('拉屎')

#调用函数
laxi()

05-11 16:05