装饰器
装饰器作用:在不改变函数内部代码的情况下来改变函数功能。
例如:
def f1():
print("F1")
def f2():
print("F2")
......
def f100()
print("F100")
某个业务部门要调用f1() f2()........f100()这100个函数,但是想在这100个函数中添加一个功能print("Log"),那么问题来了,怎么修改这100个函数?
方法一:最笨的方法,每个函数内部添加print("Log")
方法二:定义一个函数fa(),功能为print("Log"),然后在f1(),f2()...........f100()中调用fa函数
方法三:使用装饰器,不用更改函数内部代码,通过一个@符号来调用其它函数功能。
1 def outer(func): 2 3 def inner(): 4 5 print("Log") 6 7 func() #这里的func()相当于f1() 8 9 return inner 10 11 @outer #调用装饰器功能 12 13 def f1(): 14 15 print("F1") 16 17 f1() 18 19 Log 20 21 F1
分析装饰器功能实现过程:
@ + 函数名 = 装饰器
@outer
功能:
1 自动执行@后面的函数(outer),并将其下面的函数名称(f1,f2,f3..........f100)当做参数传递
2 将outer函数的返回值(inner函数体:print("Log"),重新复制给f1,f2......f100。
当我们调用函数的时候,在每一个函数前会执行print("Log")
通过两个例子我们来理解装饰器工作过程:
例:
1 def outer(func): 定义装饰器 2 3 def inner(): 4 5 print("Log") 6 7 func() 8 9 return inner
使用装饰器:
@outer def f1(): print("F1")
@outer执行过程:
第一步:传入参数f1到outer函数中
第二步:return inner即把inner函数体赋值给f1,当我们调用的时候会执行第一个f1(),即print("Log")
第三部:在第一步执行f1()的最后func()即执行一遍原来的f1(),得到值“F1”
最后按顺序输出:
Log
F1
针对于不同的需要,我们可以对函数做更改:
一 当我们只需要替换某个函数时,只需要稍作改动
1 def outer(func): 2 3 def inner(): 4 5 print("Log") 6 7 return inner 8 9 @outer 10 11 def f1(): 12 13 print("F1") 14 15 f1() 16 17 Log
二 特殊情况:当原函数有返回值的时候怎么办呢
def f1():
print("F1")
return "FFFF"
在装饰器内层函数添加一个输出返回值功能:
1 def outer(func): 2 3 def inner() 4 5 print("Log") 6 7 r = func() 8 9 print(r) 10 11 return inner 12 13 @outer 14 15 def f1(): 16 17 print("F1") 18 19 return "FFF" 20 21 f1() 22 23 Log 24 25 F1 26 27 FFF
三:当函数有参数的时候怎么办
def outer(func): def inner(a): print("前面") ret = func(a) print("后面") print(ret) return inner @outer def f1(args): print(args) return "返回值" f1("参数")
三:当不同的函数传入的参数的个数和种类不同怎么办:这里用到万能参数
1 def outer(func): 2 3 def inner(*args,**kwargs) 4 5 print("前面") 6 7 ret = func(*args,**kwargs) 8 9 print("后面") 10 11 print(ret) 12 13 return inner 14 15 @outer 16 17 def f1(args): 18 19 print(args) 20 21 return "f1的返回值" 22 23 @outer 24 25 def f2(a,b): 26 27 print(a,b) 28 29 return "f2的返回值" 30 31 f1("参数") #调用执行 32 33 f2("参数1,参数2") #调用执行 34 35 前面 36 37 参数 38 39 后面 40 41 f1的返回值 42 43 前面 44 45 参数1 参数2 46 47 后面 48 49 f2的返回值
总结:当一个函数被装饰器装饰时,这个函数被替换为装饰器的内层函数。

浙公网安备 33010602011771号