装饰器出现的原因:
写代码要遵循开放封闭原则:即已经实现的功能代码不允许被修改,但可以被扩展。
封闭:已实现的功能代码块
开放:扩展开发代码
应用需求场景:
底层开发部门实现了几个个基础功能,要被四个不同的部门调用。
需求:提出要新增一个功能
解决办法:1、四个部门自己实现:费时费工
2、定义到基础功能中:不遵循开放封闭原则
3、使用装饰器
基础功能:
def base_func1(a1, a2):
print("IT is T1")
return a1 + a2
def base_func2():
print("IT is T2")
return "True"
def base_func3():
print("IT is T3")
return "True"
现在,需要在之前功能的基础上增加功能:在功能执行前后添加欢迎信息和告别信息
编辑装饰器:add_function
def add_func(func):
def inner(*args, **kwargs):
print("Welcome you")
ret = func(*args, **kwargs)
print("Bye bye ")
return ret
return inner
使用装饰器:
@add_func
def base_func1(a1, a2):
print("IT is T1")
return a1 + a2
@add_func
def base_func2():
print("IT is T2")
@add_func
def base_func3():
print("IT is T3")
装饰器的特性:
1. 在未被调用之前,不执行,当使用@进行调用时:
@add_func
def base_func1(a1, a2)
将装饰器调用下边的函数作为参数传给装饰器函数,并将装饰器函数的返回值(一般是装饰器的内函数)重新定义传入的函数
此时,base_func1被重定义为inner,并进行执行
print("Welcome you")
ret = func(*args, **kwargs)
print("Bye bye ")
return ret
执行欢迎信息,然后执行func函数,这个func函数是在形参处接受的函数,即base_func1,然后将base_func1(*args,**kwargs)函数执行,并将其返回值赋值给ret,接着执行byebye,返回之前接收的func函数的返回值,将其返回给inner函数,inner 函数即是base_func1函数,最后,base_func1函数收到ret返回值。完成执行。
这样,在保证了开放封闭性的基础上,对函数添加了欢迎提示和告别提示。
对于多参数传入,可用*args和**kwargs 来接受,只不过要注意inner函数和执行ret = func()函数时,都有对参数个数的要求。
print(base_func1(1, 2))
base_func2()
base_func3()
执行结果:
Welcome you
IT is T1
Bye bye
3
Welcome you
IT is T2
Bye bye
Welcome you
IT is T3
Bye bye
多个装饰器
def decorator(func):
def inner1(*args, **kwargs):
print("OK")
r = func(*args, **kwargs)
print("SS")
return r
return inner1
def decorator1(func):
def inner2(*args, **kwargs):
print("OK!")
r = func(*args, **kwargs)
return r
return inner2
@decorator1
@decorator
def f1(a1, a2):
print(a1 + a2)
f1(1, 2)
result >
OK!
OK
3
SS
多装饰器原理:
靠近执行函数的装饰器和执行函数在一块,相当于产生了一个新函数,然后,新函数再和上一层的装饰器组合,进行执行操作
个人理解:多装饰器相当于对下一层的装饰器执行第二次装饰,在装饰完成后执行函数。