Python|闭包&装饰器

闭包和装饰器

一、闭包

1.定义:

通俗:函数的嵌套

在外部函数中再定义一个内部函数,一般这个内部函数需要外部函数传递过来的参数,我们把这个内部函数和这些参数组成的特殊对象(内存空间)叫做闭包

2.劣势

对于大型的项目来说,闭包可能不够,还是需要类

3.思考:函数、匿名函数、闭包、对象 当做实参时 有什么区别?
  1. 匿名函数能够完成基本的简单功能,,,传递是这个函数的引用 只有功能

  2. 普通函数能够完成较为复杂的功能,,,传递是这个函数的引用 只有功能

  3. 闭包能够将较为复杂的功能,,,传递是这个闭包中的函数以及数据,因此传递是功能+数据

  4. 对象能够完成最为复杂的功能,,,传递是很多数据+很多功能,因此传递是功能+数据

4.nonlocal--关键字

闭包内部函数调用闭包的外部函数中的局部变量

二、装饰器

1.优势:

1.在不修改函数里面代码的情况下修改或增加函数的功能,甚至调用原来代码函数的函数名都不用修改2.函数嵌套,函数调用结束,其创建空间结束3.解决:定义类的时候,Init方法中保存的值,在对象被干掉的时候才消失。其次,类空间中还包括很多其它的魔法属性和方法,也需要占用空间。所以,闭包更加节省空间,

2.功能

1.引入日志2.函数执行时间统计3.执行函数前预备处理4.执行函数后清理功能5.权限校验等场景6.缓存

3.装饰器装饰开始时间

装饰器是在遇到语法糖@就开始装饰在调用之前已经装饰了

4.装饰器装饰

1.一个装饰器可以装饰多个函数, 每装饰一个就相当于创建了一个闭包

5.通用装饰器
  1. 参数全部是多值参数,包括形参和实参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的缩进是和谁对齐@set_fun
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())


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值