装饰器
装饰器的本质就是一个函数,它的作用是在不改变被装饰函数代码及调用方式的情况下为被装饰函数加上一些功能,
可以说装饰器对于被装饰函数来说是完全透明的。
装饰器的实现方式利用了高阶函数和嵌套函数,建立装饰器的流程如下:
1.定义一个高阶函数,拥有一个函数参数
2.在高阶函数中定义一个内部函数,调用传入的函数参数完成被装饰函数的功能,其他代码实现要增加的功能
3.将内部函数作为高阶函数的返回值
4.在被修饰函数定义的时候使用语法糖@将被修饰函数的调用替换为高阶函数返回的内部函数,
从而实现在没有改变被装饰函数代码及调用方式的情况下添加新功能。
import time
#装饰器函数,作用为模拟在被装饰函数的开头和结尾添加日志
def Logger(Func):
def deco(*args,**kvargs):#可变长度参数,应对不同被装饰函数的不同参数,直接传入内部Func的
print("\nLog in start...")
Func(*args,**kvargs)
print("Log in end...")
return deco
#为装饰器函数添加非函数类型的参数,实际上就是在原来的装饰函数上再套上了一个函数,最外层的函数用于传入参数
def Logger2(params = ""):
def outer_deco(Func):
def deco(*args,**kwargs):
if params == "Type1":
print("\n按照Type1形式记录日志")
elif params == "Type2":
print("\n按照Type2方式记录日志")
Func(*args,**kwargs)
print("Log in end...")
return deco
return outer_deco
#不使用装饰器,无影响
def Func_Test1():
print("\nTest1 start")
time.sleep(1)
print("Test1 stop")
#使用装饰器,在运行前后打上日志
@Logger
def Func_Test2():
print("\nTest2 start")
time.sleep(1)
print("Test2 stop")
#使用装饰器,在运行的前后打上日志
@Logger # 这个语法糖相当于Func_Test3 = Logger,亦即Func_Test3 = deco
def Func_Test3(msg):
print("\nTest3 start")
print(msg)
time.sleep(1)
print("Test3 stop")
#带上参数的装饰函数,此时变成了Func_Test4 = Logger2()
@Logger2()
def Func_Test4():
print("\nTest4 start")
time.sleep(1)
print("Test4 stop")
@Logger2(params ="Type2")
def Func_Test5(msg = ""):
print("\nTest5 start")
print(msg)
time.sleep(1)
print("Test5 stop")
调用
Func_Test1()
Func_Test2()
Func_Test3("传入参数")
输出
Test1 start
Test1 stop
Log in start...
Test2 start
Test2 stop
Log in end...
Log in start...
Test3 start
传入参数
Test3 stop
Log in end...
调用
Func_Test4()
Func_Test5("传入参数")
输出
Test4 start
Test4 stop
Log in end...
按照Type2方式记录日志
Test5 start
传入参数
Test5 stop
Log in end...