装饰器本质上是一个Python函数,其可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。而实现装饰器的方式叫做闭包。闭包函数可以看这篇。
定义一个闭包函数:其返回结果为wrapper函数
def fun(a):
def wrapper():
print('---start---')
print(a)
print('----end---')
return wrapper
b = fun(11)
print(b)
b()
运行结果:
<function func.<locals>.wrapper at 0x00000242C3D9B430>
---start---
111
----end---
其执行顺序,调用fun函数时传入变量a,其返回结果为内部函数wrapper 赋值给了b,所以可以通过b()去调用wrapper函数执行内部函数。
继续现有函数func2功能如下:
def func2():
print('我是func2')
将函数名func2作为参数传给func,来看下运行结果
def func(a):
def wrapper():
print('---start---')
print(a)
print('----end---')
return wrapper
def func2():
print('我是func2')
b = func(func2)
b()
运行结果:
---start---
<function func2 at 0x000002879DADB430>
----end---
结果a为传进去的func2函数,所以通过a()则可以调用func2函数:
def func(a):
def wrapper():
print('---start---')
print(a)
a()
print('----end---')
return wrapper
def func2():
print('我是func2')
b = func(func2)
b()
运行结果:
---start---
<function func2 at 0x0000029F711BB430>
我是func2
----end---
其结果显然func2函数被func装饰器修饰。
而在使用装饰器来装饰函数时,只需要在被装饰的函数前面,使用 "@装饰器函数名“ 的形式来装饰,则函数本身的功能正常实现,装饰器中添加的功能也实现了。如下:
# 装饰器函数
def func(a):
def wrapper():
print('---start---')
a()
print('----end---')
return wrapper
@func # 调用装饰器
def func2():
print('我是func2')
@func #调用装饰器
def func3():
print('我是func3')
# 其中@func的语法同等于 b = func(func2) ,b()
func2() 运行结果:
---start---
我是func2
----end---
func3 运行结果:
---start---
我是func3
----end---