一、定义与作用
1、定义:装饰是指为其他事物添加额外的点缀,器是指工具,比如函数。也就是说装饰器可以是一个用来为其他函数添加功能的函数。
2、用途:实现装饰对象的开放与封闭:
①开放:是指对功能拓展的开放。
②封闭:是指对源代码和调用方式的封闭。
③总结:装饰器就是在不修改装饰对象的源代码和调用方式的前提下为其增加新功能。
二、分解装饰器的实现步骤:
1、定义一个初始函数。
def add(a, b): print(a + b) add(1, 2)
2、在函数定义阶段的函数体内直接增加新功能。
def add(a, b): print(a + b) print('新功能') add(1, 2) # 没有修改函数的调用方式,但是修改了其源代码
3、新功能移到函数体外。
def add(a, b): print(a + b) add(1, 2) print('新功能') # 没有修改函数的源代码也没有修改调用方式,但是代码变得冗余
4、新建函数,把原函数的调用和新功能定义进新函数。
def add(a, b): print(a + b) def hide(): add(1, 2) print('新功能') hide() # 没有修改原函数的源代码,但是调用方式变了,且函数被写死了
5、把原函数的参数写活。
def add(a, b): print(a + b) def hide(*args, **kwargs): add(*args, **kwargs) print('新功能') hide(1, b=2) # 可以通过改变传入函数hide的实参间接控制传入add的实参,且通过可变长度参数的中转, # hide本身传入的实参值的形式和数量可以是任意的,只需对应函数add的形参即可 # 如此便实现了用函数hide装饰函数add的效果
6、可以装饰不同的原函数。
def add(a, b): print(a + b) def passer(func): def hide(*args, **kwargs): func(*args, **kwargs) print('新功能') return hide # 给装饰函数hide包起来,通过给外包函数passer传入原函数名来控制装饰函数所装饰对象, # 再让外包函数passer返回出装饰函数hide add = passer(add) # 再把返回的装饰函数hide再赋值给新的变量add,此时新的add则拥有了原函数add的功能 add(1, 2) # 看上去是在调用原函数add,实际是在调用拥有新功能的add
7、装饰函数也可以返回原函数的返回值。
def add(a, b): print(a + b) return '原函数的返回值' def passer(func): def hide(*args, **kwargs): res = func(*args, **kwargs) print('新功能') return res # 如此装饰函数hide的返回值就是原函数add的返回值 return hide add = passer(add) print(add(1, 2))
三、语法糖:简便的语法@。
1、基本使用:
def passer(func): def hide(*args, **kwargs): res = func(*args, **kwargs) print('新功能') return res return hide @passer # 在被装饰对象正上方的单独一行写@装饰器名字即代表本函数定义完默认被该装饰器装饰,相当于执行了add = passer(add) def add(a, b): print(a + b) return '原函数的返回值' print(add(1, 2))
2、增加多个装饰器:
@passer3 @passer2 @passer1 def add(a, b): print(a + b) return '原函数的返回值' # 会按照由下到上,即跟原函数相比由近到远依次装饰
四、无参装饰器模板
def passer(func): def hide(*args, **kwargs): res = func(*args, **kwargs) return res return hide # 未增加新功能的装饰器,在此基础上可以定义为用于新增各种功能的不同装饰器