闭包函数
闭包函数=函数嵌套定义+函数对象+名称空间与作用域
1.闭:指的是该函数定义在一个函数的内部
2.包:指的是该函数访问了一个来自外层函数的变量
为函数体传参:
方案一:直接使用参数的形式传递
方案二:把函数体想要的参数包给它,即是在外层包一个函数,并且将参数作为外层函数的参数导入进来,这样该函数就能获取该参数
装饰器
1.什么是装饰器
器:工具
装饰:为被装饰的函数添加额外的功能
2.为何要有装饰器
软件一旦上线运行之后,就应该遵循开放封闭原则:
1.开放指的是对拓展功能的开放
2.封闭指的是对修改源代码封闭
定义装饰器的目的:
定义装饰器就是为了在遵循1和2的前提下来为其他函数添加新功能的
ps:
不修改被装饰对象指的是定义与调动都不能修改
所以下述行为都违反了开放封闭原则:
1.修改被装饰对象定义时的源代码
2.修改被装饰对象的调用方式
3.如何使用装饰器
无参装饰器
通过不断优化及总结下来的模板(详见pycharm演示代码):
def outter(func):
def wrapper(*args,**kwargs):
res=func(*args,**kwargs)
return res
return outter
@outter
(被装饰函数)
有参装饰器
有参装饰器的模板:
(在无参装饰器的基础上再添加导入参数,且是以再包一层的形式)
def outter2(x,y,z,a,b):
def outter1(func):
def wrapper(*args,**kwargs):
res=func(*args,**kwargs)
return res
return wrapper
return outter1
叠加多个装饰器
1.加载顺序:自下而上
index=wrapper1的内存地址 index=wrapper1 被先执行 所以被赋予相同的函数名
deco1(wrapper2的内存地址)=>wrapper1的内存地址 wrapper2=deco1(wrapper2)=wrapper1
deco2(wrapper3的内存地址)=>wrapper2的内存地址 wrapper3=deco2(wrapper3)=wrapper2
deco3(最原始的那个被装饰函数的内存地址)=>wrapper3的内存地址 index=deco3(index)=wrapper3
这是一个建立各装饰器与原函数关系的一个过程,每一层都带着原函数的内存地址,当执行完装饰器后,最外层的装饰器会带着原函数加工的每一层功能返回到全局打印。
2.执行顺序:从上到下
从上到下执行,遇到了内装饰器的内存地址就去执行内装饰器,一直运行到原函数执行完然后返回值,然后再按原轨迹自下而上的依次调回到原来的执行点继续执行并return。(注意这是一个自然结束的过程,最内层装饰器包含着原函数,原函数结束了那么跟着结束的就是内层装饰器,依次类推结束到最外层装饰器。)