闭包 与 装饰器
-
函数参数
-
函数名存储了函数所在的空间地址
-
函数名+ () 到函数所在的空间执行里面的代码
-
闭包:
-
发生函数嵌套
-
外层函数的返回值是内层函数的函数名(地址/引用)
-
外层函数有参数(内层函数使用到)
-
节省系统资源 提高代码复用率的一种特殊语法
-
语法格式
-
def 外层函数(参数):def 内层函数():passreturn 内层函数
-
-
闭包流程
-
执行第五行 调用func_out
-
执行2,3 行 func_in函数 只定以不执行 开辟一个空间 暂且定为 0x11(),所以func_in=0x11
-
执行第四行 返回func_in 也就是0x11
-
然后到第五行 usa_rate= func_in= 0x11
-
执行第六行 0x11(100) = fun_in()
-
执行2,3 行代码
-
1 1.def func_out(rate): 2 2. def func_in(money): 3 3. print(rate * money) 4 5 4. return func_in 6 7 5.usa_rate = func_out(0.7) 8 6.usa_rate(100)
-
-
nonlocal ------ 声明外层函数的变量
-
装饰器
-
在不改变原有代码的前提下 还可以给函数增加新的功能
-
使用方法
-
@新加功能的函数名
-
装饰器下面正好是函数
-
自动执行 login = func_out(login)
-
执行流程
-
执行第六行,首先装饰器会自动执行一句话 login = func_out(login)
-
把7,8行代码开辟一个空间地址暂且叫做0x22, 当作参数传给第一行func
-
执行第一行 0x22传递给func
-
2,3,4函数只定以不执行开辟一个空间地址 暂且是 0x11
-
执行第五行 返回func_in = =0x11 给函数调用者, 也就是 login = func_in== 0x11
-
然后执行login() == 0x11()==func_in(),到2,3,4代码
-
第四行 func() == login ==0x22=7,8行代码
-
*** 执行流程结论***
-
func ==> 原始login 也就是0x22
-
新的login()0x11 ==>func_in()
-
1.def func_out(func): 2. def func_in(): 3. print("验证") 4. func() 5. return func_in 6.@func_out 7.def login(): 8. print("登录") 9.login()
-
通用版装饰器
def func_out(func): def func_in(*args,**kwargs): return func(*args,**kwargs) return func_in @func_out def login(*args,**kwargs): print(args) print(kwargs)
login(10,30,age = "123",name = "qwe")
-
多重装饰器
-
执行流程
-
1.def func_out01(func01): 2. print("func_out01 is show") 3. def func_in01(): 4. print("func01 is show") 5. func01() 6. return func_in01 7.def func_out02(func02): 8. print("func_out02 is show") 9. def func_in02(): 10. print("func02 is show") 11. func02() 12. return func_in02 13.@func_out02 14.@func_out01 15.def login(): 16. print('login is show') 17.login() 答案: func_out01 is show func_out02 is show func02 is show func01 is show login is show
-
首先执行13行 装饰器func_out02下面不是函数,所以执行14行,
-
把15.16行开辟一个空间暂且定义为0x11 ,把0x11当作参数传递给func01暂且存起来
-
执行func_out01,自动执行login = func_out(login) login = 0x11 = func01
-
执行第二行 得出第一个结果 --- func_out01 is show
-
3,4,5只定以不执行 开辟一个空间 暂且定义以为 0x22
-
返回 0x22 新login = 0x22 = func_in01
-
14行变为一个函数
-
执行装饰器13行 自动执行 0x22=func_in01 == func_out02(0x22)
-
执行10行 func_in01 = func02 = 0x22 得出第二个结果 ----- func_out02 is show
-
把9,10,11 封装起来 开辟一个空间 称为 0x33
-
执行12行 返回给函数调用者 login = func_in02()
-
这时候执行login()
-
执行9,10,11 行代码得出 第三个结果--- func02 is show
-
执行11行 fun02() = func_in01()-----得出func01 is show
-
执行fun01() 得出 == login is show fun01() = login
-