装饰器

装饰器作用:在不改变函数内部代码的情况下来改变函数功能。

例如:

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的返回值

 

 

 

总结:当一个函数被装饰器装饰时,这个函数被替换为装饰器的内层函数。

 

posted @ 2016-09-11 23:25  hehe88  阅读(162)  评论(0)    收藏  举报