闭包函数以及装饰器的原理
前言:
本文为在霍格沃兹测试开发学社的学习经历分享
闭包函数
1. 闭包函数
- 闭包的内部函数中,对外部作用域的变量进行引用
- 闭包无法修改外部函数的局部变量
- 闭包可以保存当前的运行环境
2. 闭包函数的条件
-
需要一个嵌套函数,也就是说得有一个外部函数,有一个内部函数,内部函数定义在外部函数里面,成为内函数和外函数;
-
内函数引用了外函数的临时变量(一个在外函数中的局部变量);
-
外函数返回的是内函数这个函数对象。
注意:闭包函数的每一次调用都会开辟新的内存空间,所以使用的时候需要关注下内存的使用情况。
3. 闭包函数的使用
def student_grade(grade):
def inner(name,age):
print(f"开学啦,学生的名称是{name},性别是{age},年级是{grade}")
return output_students
stu= student_grade(1) # 调用外层函数,返回的是内层函数的对象
print(stu)
stu('张三','男')
inner函数对外部的student_grade函数的参数进行了引用
装饰器
- 装饰器是一种可以装饰其他函数的工具,本质上是一个闭包函数,
1. 面试题:装饰器的作用
- 装饰器的作用就是为已经存在的对象添加额外的功能,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并重复使用。
- 装饰器的返回值也是⼀个函数的对象,它经常用于有切面需求的场景,比如:插入日志、事务处理等场景。
- 优化代码的可读性和可维护性
2.自定义装饰器的使用
- 使用:在被装饰函数上使用@+装饰器名称即可
- 注意:装饰器不能装饰@staticmethod 或者 @classmethod已经装饰过的方法,会报错。
# 1. 定义内函数和外函数
# 5. 在装饰器执行过程中,会自动传入一个参数,参数就是被装饰函数的函数对象
def timer(func):
def inner():
# 2. 执行装饰器逻辑
print("函数开始执行")
func() # 第六步,添加被装饰函数的执行步骤
print(func)
print("函数结束执行")
# 3. 把内函数对象return出去
return inner
#4. 装饰器的使用
@timer
def hogwarts():
print("hogwarts")
def hogwarts1():
print("hogwarts1")
hogwarts()
注意:
- 如果被装饰函数有参数,那么需要再内函数加形参,以及在函数调用传入实参
- 可以把内函数的参数设置成不定长形参,这样不管被装饰函数有多少个参数都可以正常执行
import datetime
def timer(func):
def inner(*args,**kwargs):
start_time = datetime.datetime.now()
func(*args,**kwargs)
end_time = datetime.datetime.now()
print(f"函数的执行时间为{end_time-start_time}")
return inner
@timer
def hogwarts(name,age,gender):
print("霍格沃兹测试学社",name,age,gender)
hogwarts("123",124,45)