前置知识:
- 函数的本质就是变量名
- 可以把函数作为参数传递,例如:
def func():print("我是func")# 接收的fn是个函数
def handle(fn):
# 调用函数fn()handle(func)
- 可以把函数作为返回值返回,例如
def func():def func2():print("我是func2")# func2函数作为返回值return func2fn = func()
fn()
闭包
闭包:内层函数对外层函数的变量的使用
作用1:让一个变量被外部访问,但是不能修改
作用2:让一个变量常驻内存
def func():a = 10def inner():print(a)return areturn inner# 函数外部访问到了变量a
fn = func()
fn()
装饰器
本质: 装饰器的本质就是一个函数,该函数的参数是被装饰的函数,返回值是装饰后的函数
作用: 装饰器可以在不改变原有代码的基础上,给函数添加新的功能
一、装饰器雏形(理解)
装饰器雏形
def wrapper(fn):def inner():print("执行被装饰函数之前")fn()print("执行被装饰函数之后")return innerdef add():print("我是add")# 向wrapper函数传入了add函数,返回的函数命名为add
add = wrapper(add) # 装饰器的关键语句!!!
add() # 这里执行add()相当于执行inner(),因为wrapper返回的是inner函数
装饰器雏形用语法糖的形式写
def wrapper(fn):def inner():print("执行被装饰函数之前")fn()print("执行被装饰函数之后")return inner@wrapper # 用语法糖/装饰器的写法应该这么写,等价于执行add = wrapper(add)
def add():print("我是add")add() # 这里执行add()相当于执行inner(),因为wrapper返回的是inner函数
二 、通用装饰器(重点记住)
通用装饰器的固定写法如下:
(wrapper、inner、fn都是可以随意命名的,并非固定的)
def wrapper(fn):# *args和**kwargs用于接受被装饰函数的参数def inner(*args, **kwargs):"""在被装饰函数之前执行的操作"""# 注意:这里的*和**是将args和**kwargs打散传递给fn函数ret = fn(*args, **kwargs) # 被装饰函数"""在被装饰函数之后执行的操作"""return ret # 处理被装饰函数的返回值return inner
三、高阶装饰器(理解)
即同一个函数被多个装饰器装饰
四、带参数的装饰器(理解)
举例: