装饰器,为原函数扩展新功能,用新功能区替代旧功能,在不改变原有的代码基础上,实现功能的扩展
闭包函数内涵数使用了外函数的一个局部变量,外函数还把内涵数返回来的一个过程,内涵数为闭包,返回过来的函数替换外函数
1.基础写法,闭包函数原理:用新函数替换旧函数,
def kuozhang(func):
def newfunc():
print("测试前")
func()
print("测试后")
return newfunc
def func():
print("我叫")
# func=kuozhang(func)=newfunc
func=kuozhang(func)
func()
2.@语法糖,自动会把@符号下面的函数当成参数传给装饰器,
把新函数进行返回,用新函数替换旧的函数,
def kuozhang(func):
def newfunc():
print("测试前")
func()
print("测试后")
return newfunc
@kuozhang
def func():
print("我叫")
# func=kuozhang(func)=newfunc
# func=kuozhang(func)
func()
3.装饰器的嵌套
def kuozhan(func):
def newfunc():
print("厕所前3")
func()
print("厕所后,牛头马面4")
return newfunc
def kuozhang2(func):
def newfunc():
print("测试前1")
func()
print("测试后2")
return newfunc
@kuozhang2
@kuozhan
def func():
print("我是谁5")
func()
先调用扩展,然后调扩展2,从下(2)到上进行传递,把3,5,4包装饰好的东西向上传
4.用装饰器修饰带有参数的函数,扩展的新功能和原函数的功能,在参数和返回值上要保持一致
def funcsion(func):
def newfunc(who,where):
print("我爱小多多1")
func(who,where)
print("我爱小多多2")
return newfunc
@funcsion
def func(who,where):
print("{}在{}看电影".format(who,where))#左边是关键字,右边是值
func("小多多","成龙电影院")
#5.用装饰器修饰带有参数返回值的函数
print("======")
def kuozhan(func):
def newfunc(*args, **kwargs): # 函数的定义处,*号的打包
print("测试前")
res1= func(*args, **kwargs) # 函数的调用处,*号的解包
print("测试后")
return res1
return newfunc
@kuozhan
def func(*args,**kwargs):#搜集参数
dic={"xiaoduoduo":"多多","guheng":"古横"}
lst=[]
strvar=""
print(args)
print(kwargs)
for k,v in kwargs.items():
# strvar=dic[k]
print(k,v)
strvar=dic[k] +"留下"+v+"黄金"
lst.append(strvar)
return lst
推导式
return [dic[k] +"留下"+v+"黄金"for k,v in kwargs.items()]
res=func(xiaoduoduo="1克",guheng="10克")
print(res)
print("++++++++++++++++")
6用类装饰器来扩展原函数
class Kuozhang0():
def kuozhang1(func0):
def funcc():
print("吃之前")
func0()
print("吃之后")
return funcc
@Kuozhang0.kuozhang1
def func0():
print("ni 吃的真多")
func0()
class Kuozhang0():
def __call__(self,func0):
return self.kuozhang2(func0)
def kuozhang1(self,func0):
def funcc():
print("吃之前")
func0()
print("吃之后")
return funcc
def kuozhang2(self,func0):
def newfunc():
print("拉之前")
func0()
print("拉之后")
return newfunc
@Kuozhang0()#aaKuozhang0()=obj对象=》obj(func0),把对象当成函数使用了,自动触发call方法
把新函数返回了=@发动第二个技能,将新函数替换旧函数,func0=kuozhang2 func()《=》kuozhang2()
def func0():
print("ni 吃的真多")
func0()