python中的闭包和修饰器
学习:https://www.bilibili.com/video/BV1JW411i7HR?from=search&seid=16657644362313549009
一、闭包demo1
闭包概念:内部函数对【外部函数作用域里的变量】的引用
1.现在函数ouFunc()内部有一个函数innerFunc(),代码如下:
1 ''' 2 @author:invoker 3 @project:fastApiStudy 4 @file: bibao1.py 5 @contact:invoker2021@126.com 6 @descript: 7 @Date:2021/8/5 12:36 8 @version: Python 3.7.8 9 ''' 10 11 """ 12 闭包:内部函数对[外部函数作用域里变量]的引用 13 14 """ 15 16 17 def outFunc(): 18 print('this is outFunc') 19 def innerFunc(): 20 print('this is innerFunc') 21 22 outFunc() 23 innerFunc()
执行结果:innerFunc未定义,因此不能再外面直接调用innerFunc函数。
innerFunc()内部函数只有在外部函数outFunc()执行过程中才能被创建,当outFunc()的生命周期结束,则innerFunc()也被销毁
2.将内部函数返回(保持)给一个变量,然后在外部调用这个变量,且在后面加上括号。
1 ''' 2 @author:invoker 3 @project:fastApiStudy 4 @file: bibao1.py 5 @contact:invoker2021@126.com 6 @descript: 7 @Date:2021/8/5 12:36 8 @version: Python 3.7.8 9 ''' 10 11 """ 12 闭包:内部函数对[外部函数作用域里变量]的引用 13 14 """ 15 16 def outFunc(): 17 print('this is outFunc') 18 def innerFunc(): 19 print('this is innerFunc') 20 return innerFunc 21 22 v1 = outFunc() 23 v1()
3.外部函数内定义内部变量a,内部函数定义参数Num
1 ''' 2 @author:invoker 3 @project:fastApiStudy 4 @file: bibao1.py 5 @contact:invoker2021@126.com 6 @descript: 7 @Date:2021/8/5 12:36 8 @version: Python 3.7.8 9 ''' 10 11 """ 12 闭包:内部函数对[外部函数作用域里变量]的引用 13 14 """ 15 16 17 def outFunc(): 18 print('this is outFunc') 19 a = 1 20 21 def innerFunc(num): 22 print('this is innerFunc') 23 print(num + a) 24 25 return innerFunc 26 27 28 v1 = outFunc() 29 v1(3)
返回值是 3+1 = 4.
因此,闭包:内部函数对【外部函数作用域里的变量】的引用。就说明这是一个闭包。
闭包内的闭包函数是innerFunc(num),私有化了外部函数outFunc()内的变量a,完成了数据的封装。
4.demo2
1 ''' 2 @author:invoker 3 @project:fastApiStudy 4 @file: bibao1.py 5 @contact:invoker2021@126.com 6 @descript: 7 @Date:2021/8/5 12:36 8 @version: Python 3.7.8 9 ''' 10 11 """ 12 闭包:内部函数对[外部函数作用域里变量]的引用 13 14 """ 15 16 17 def outFunc(): 18 print('this is outFunc') 19 a = 1 20 21 def innerFunc(num): 22 print('this is innerFunc') 23 print(num + a) 24 25 return innerFunc 26 27 28 v1 = outFunc() 29 v1(3) 30 31 mylist = [1,2,3,4,5] 32 33 def func1(obj): 34 print('func1:',obj) 35 def func2(): 36 obj[0]+=1 37 print('func2:',obj) 38 return func2 39 40 v2 = func1(mylist) 41 v2() 42 v2() 43 v2() 44 del v2
v2就是一个闭包,将mylist保存下来,且还可以对mylist进行多次更改,只有当del v2后,mylist就不存在了。
二、装饰器,又叫语法糖@,通过闭包原理实现装饰器
装饰器不影响原来的函数的功能,只能在原函数上新增新的功能。
装饰器和闭包的区别在于:
装饰器中内部函数也有返回,返回的是函数调用。
闭包中内部函数没有返回值,只有外部函数有返回值
1 ''' 2 @author:invoker 3 @project:fastApiStudy 4 @file: zsq1.py 5 @contact:invoker2021@126.com 6 @descript: 7 @Date:2021/8/5 13:31 8 @version: Python 3.7.8 9 ''' 10 11 12 def func1(func): # 外部闭包函数的参数是被装饰的函数对象func 13 def func2(): 14 print("new function") 15 return func() # 返回外部函数的参数 16 17 return func2 18 19 20 @func1 21 def myprint(): 22 print("this is print1") 23 24 25 def myprint2(): 26 print("this is print2") 27 28 29 myprint() 30 # myprint() 等于执行 func1(myprint)() 31 func1(myprint2)() 32 # func1(myprint2)() 等于@func1的效果
三、装饰器带参数:
1 ''' 2 @author:invoker 3 @project:fastApiStudy 4 @file: param_zsq.py 5 @contact:invoker2021@126.com 6 @descript: 7 @Date:2021/8/5 14:13 8 @version: Python 3.7.8 9 ''' 10 11 # 第一层是装饰器的参数 12 def arg_func(sex, old): 13 # 第二层函数是用来调用被装饰函数 14 def func1(func): 15 # 第三层是装饰器内部封装的内容 16 def func2(): 17 if sex == 'man': 18 print("男人不能生孩子") 19 if sex == 'woman' and old < 18: 20 print("女人未到18岁,不可以生孩子") 21 if sex == 'woman' and old > 50: 22 print("女人岁数太大,不可以生孩子") 23 if sex == 'woman' and (old >= 18 and old <= 50): 24 print("女人岁数刚好,可以生孩子") 25 return func() 26 return func2 27 28 return func1 29 30 31 @arg_func(sex='man', old=18) 32 def man(): 33 print('努力工作!') 34 35 36 @arg_func(sex='woman', old=35) 37 def woman(): 38 print('努力工作!') 39 40 41 man() 42 woman() 43 44 def woman1(): 45 print('woman1 努力工作!') 46 47 arg_func(sex='woman',old=38)(woman1)()
四、被装饰函数带参数
被装饰函数带参数,如果想对参数做更改,需要将被装饰函数的参数放在装饰器最内层的函数中
1 ''' 2 @author:invoker 3 @project:fastApiStudy 4 @file: b_func_param.py 5 @contact:invoker2021@126.com 6 @descript: 7 @Date:2021/8/5 15:14 8 @version: Python 3.7.8 9 ''' 10 11 12 # 被装饰函数带参数,如果想对参数做更改,需要将被装饰函数的参数放在装饰器最内层的函数中 13 def func1(func): 14 def func2(x, y): 15 x += 2 16 y += 3 17 return func(x, y) 18 19 return func2 20 21 22 @func1 23 def mysum(a, b): 24 print(a + b) 25 26 27 mysum(1, 2) 28 29 30 def mysum2(a, b): 31 print(a + b) 32 33 34 func1(mysum2)(1, 2)
综合三,四,装饰器的参数在最外层,被装饰的参数在最内层,中间层则是被装饰的函数
本文来自博客园,作者:kaer_invoker,转载请注明原文链接:https://www.cnblogs.com/invoker2021/p/15103507.html