装饰器小结
1.在进入装饰器之前先看先一下闭包:
1 def w1():
2 def w2():
3 print("实现封装的功能")
4 return w2
5 t=w1()
6 t()
2.装饰器其实就是在运用闭包封装功能的基础的基础上实现的,并且又用运了了python的一种语法糖:@XXX
下面给出一个简单的例子:
1 def w1(fun):
2 print("w1开始执行")
3 def w2():
4 print("验证功能")
5 t = fun()
6 return t
7 return w2
8 @w1
9 def test():
10 print("fun功能功能被调用")
11 return "将要被封装的功能"
12 print(test)
13 print(test())
14 test()
15 print(w1)
16 print(test)
17 print(id(w1))
18 print(id(test))
运行结果:
w1开始执行
<function w1.<locals>.w2 at 0x7f5f7b91e7b8>
验证功能
fun功能功能被调用
将要被封装的功能
验证功能
fun功能功能被调用
<function w1 at 0x7f5f7b91e6a8>
<function w1.<locals>.w2 at 0x7f5f7b91e7b8>
140048071780008
140048071780280
画个示意图:
装饰器的基本原理可以通过以上这个例子进行验证,接下来进入正题,那么装饰器到底是个什么呢?接下来结合上面的例子说一下装饰器的原理:
装饰器原理:上面有个Python语法糖@w1,它的的作用就是执行w1函数指导print(“w1开始执行”)跳过w2 函数放到内存中但并不执行,指导return w2 返回到w2函数,此时@w1结束,它的另一个作用就是把它下面的test的函数当做参数传给w1函数,并且把w1 的返回值w2函数换个新的函数名就是,总的形式就是:新test=w1(test)执行完之后便是是新test=w2(),此时test是新的test函数,而原来的test函数的被fun接受,相当于fun=原test函数这可以在以上实例得到验证。
以下是装饰器的运用的实例:
1.含参数的装饰器:
1 def w1(fun):
2 def w2(a,b):
3 print("验证模块")
4 print(a,b)
5 t=fun(a,b)
6 return t
7 return w2
8 @w1
9 def test(a,b):
10 print("封装模块")
11 print(a+b)
12
13 test(3,2)
2.含不定参数的装饰器:
1 def w1(fun):
2 def w2(*args,**kwargs):
3 print("验证功能模块")
4 t = fun(*args,**kwargs)
5 return t
6 return w2
7 @w1
8 def test(a,b,c):
9 print(a*b-c)
10
11 test(2,3,1)
3.装饰器带参数:
1 def w1(id):
2 def w2(fun):
3 def w3(*args,**kwargs):
4 print("开启验证功能")
5 if id > 3:
6 print("验证成功")
7 t = fun(*args,**kwargs)
8 return t
9 else:
10 print("验证失败")
11 return w3
12 return w2
13 id=int(input("请输入id:"))
14 @w1(id)
15 def test(a,b,c):
16 print(a*b+c)
17
18 test(1,2,1)
4.类装饰器:
1 class w1():
2 def __init__(self,fun):
3 print("初始化")
4 self.fun=fun
5 def __call__(self):
6 self.fun()
7 print("进程结束")
8 @w1
9 def test():
10 print("封装功能实现")
11
12 test()
做个小结吧:
其实装饰器很简单,关键是魔法糖的出现让闭包变成了装饰器,单纯的闭包的思想此刻开始他的精彩表演,其实一看到@xxx,就应该明锐而迅速的明确以下几个要点,@xxx下面的函数是就是要封装的函数,这点毫无疑问,就是要把它当做参数传入xxx()的括号里面,于此同时把他的函数名拿出就是:test=xxx(test)这种形式,这里用fun来接受test的原函数,当新test() #调用的时候,便是相当于新test=w2(fun),执行w2()函数的内容,当发现调用fun()的时候便是相当于调用了原test()的函数。
下面是结合上边内容匹配的内容:
1 def w1(fun):
2 def w2():
3 fun()
4 return w2
5 @w1
6 def test():
7 print("封装的功能")
8 test()
注意:test()的参数布置和w2()的参数布置是相似的以及fun()的参数布置都是一致的。
如果看不懂的地方请留言说明地方