Python|闭包&装饰器
程序员文章站
2022-07-12 23:49:03
...
闭包和装饰器
一、闭包
1.定义:
通俗:函数的嵌套
在外部函数中再定义一个内部函数,一般这个内部函数需要外部函数传递过来的参数,我们把这个内部函数和这些参数组成的特殊对象(内存空间)叫做闭包
2.劣势
对于大型的项目来说,闭包可能不够,还是需要类
3.思考:函数、匿名函数、闭包、对象 当做实参时 有什么区别?
匿名函数能够完成基本的简单功能,,,传递是这个函数的引用 只有功能
普通函数能够完成较为复杂的功能,,,传递是这个函数的引用 只有功能
闭包能够将较为复杂的功能,,,传递是这个闭包中的函数以及数据,因此传递是功能+数据
对象能够完成最为复杂的功能,,,传递是很多数据+很多功能,因此传递是功能+数据
4.nonlocal--关键字
闭包内部函数调用闭包的外部函数中的局部变量
二、装饰器
1.优势:
1.在不修改函数里面代码的情况下修改或增加函数的功能,甚至调用原来代码函数的函数名都不用修改2.函数嵌套,函数调用结束,其创建空间结束3.解决:定义类的时候,Init方法中保存的值,在对象被干掉的时候才消失。其次,类空间中还包括很多其它的魔法属性和方法,也需要占用空间。所以,闭包更加节省空间,
2.功能
1.引入日志2.函数执行时间统计3.执行函数前预备处理4.执行函数后清理功能5.权限校验等场景6.缓存
3.装饰器装饰开始时间
装饰器是在遇到语法糖@就开始装饰在调用之前已经装饰了
4.装饰器装饰
1.一个装饰器可以装饰多个函数, 每装饰一个就相当于创建了一个闭包
5.通用装饰器
参数全部是多值参数,包括形参和实参2.return 返回,函数(多值参数)
6.一个装饰器装饰多个函数
1.从下面的语法糖开始往上装2.运行的时候从最外层的语法糖往内执行,主程序最先运行完,但是最开始运行的语法糖即最外层(最上面)的语法糖最后执行完
7.疑问:1. 多个装饰器中的内嵌函数同名,会不会影响结果
不会。因为他们虽然函数名相同,但是他们的空间(作用域)不同,一个是局部变量的指向,一个是全局变量的指向
三、demo
1.闭包
def set_fun(func): def call_func(*args, **kwargs): # 这里的参数是报这个闭包搞成通用的 print("---这是要装饰的1---") print("---这是要装饰的2---") func(*args, **kwargs) # 拆包 return call_func # 注意这里返回的是内嵌函数的引用,而不是调用内嵌函数;同时注意return的缩进是和谁对齐 # 原主函数 def test(): print("---我是原来的函数,你不能动我的内部代码---") a = set_fun(test) a() # 调用a ======> 搞成装饰器--修改调用方式: test=set_fun(test) test()
2.装饰器
def set_fun(func): def call_func(*args, **kwargs): # 这里的参数是报这个闭包搞成通用的 print("---这是要装饰的1---") print("---这是要装饰的2---") return func(*args, **kwargs) # 拆包 return call_func # 注意这里返回的是内嵌函数的引用,而不是调用内嵌函数;同时注意return的缩进是和谁对齐 def test(): print("---我是原来的函数,你不能动我的内部代码---") return "返回想返回的值" # 调用装饰器 test() --->可以选择传入参数或不传
# 类作为装饰器
class Test(object):
def __init__(self, func):
self.func = func
def __call__(self):
print("这里是装饰器添加的功能.....")
return self.func()
@Test # 相当于get_str = Test(get_str)
def get_str():
return "haha"
print(get_str())