一、装饰器的简介
可以在不修改原函数的情况下扩展旧函数得到新函数
为了可以在不修改源代码的情况下对函数进行扩展,
为了解决这个问题,我们创建一个函数,让这个函数可以自动的帮助我们生产函数
二、装饰器的使用方法
让 new_function() 接收任意数量参数
让 new_function() 接收所有函数参数,需要再括号中填入 *args,**kwargs
,并在 old() 括号中也填入 *args,**kwargs
。
*args
接收任意数量位置参数**kwargs
接收任意数量关键字参数
# 在 def begin_end(): 括号中加入 old
def begin_end(old):
'''
用来对其他函数进行扩展,
使其他函数可以在执行前打印开始执行,
执行后打印执行结束
参数:
old 要扩展的函数对象
'''
# 创建一个新函数
# 在这里:*args 把参数装包成元组, **kwargs 把参数装包成字典
def new_function(*args,**kwargs):
print('开始执行~~~')
# 调用被扩展的函数
# 而这里:*args 把元组拆包成位置参数传入函数
# **kwargs 把字典拆包成关键字参数
result = old(*args,**kwargs)
print('执行结束~~~')
# 返回函数的执行结果
return result
# 返回新函数
return new_function
f = begin_end(fn) # (填入需要扩展的函数对象)
f2 = begin_end(add)
f()
print('-'*10)
r = f2(123,456)
print(r)
直接 用 begin_end (填入需要扩展函数)
像本例中的 begin_end() 这种函数我们就称为装饰器
使用装饰器
- 在定义函数时,可以通过
@
装饰器,来使用指定的装饰器,来装饰当前函数 - 可以为一个函数指定多个装饰器,这样函数将会按照从内向外的顺序被装饰
如再定义一个跟begin_end一样的名为fn3的装饰器,然后使用多个装饰器:
# 先用fn3进行装饰,再用begin_end进行装饰fn3装饰后的函数
@begin_end
@fn3
def say_hello():
print('大家好~~~')
say_hello()
# 执行结果:
@begin_end开始执行~~~
@fn3开始执行~~~
大家好~~~
@fn3执行结束~~~
@begin_end执行结束~~~
三、装饰器的好处
- 可以修改多个函数
- 方便后期的维护
- 不违反开闭原则(OCP)
o: OPEN , c: CLOSE , p: 原则 。程序的设计,要求开放对程序的扩展,要关闭对程序的修改。