14 Python 装饰器

Posted 潘红伟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了14 Python 装饰器相关的知识,希望对你有一定的参考价值。

装饰器

  装饰器其实就是一个以函数作为参数并返回一个替换函数的可执行函数。让我们从简单的开始,直到能写出实用的装饰器。

技术分享
 1 def outer(some_func):
 2     def inner():
 3         print "before some_func"
 4         ret = some_func() # 1
 5         return ret + 1
 6     return inner
 7 def foo():
 8     return 1
 9 decorated = outer(foo) # 2
10 decorated()
11 
12 before some_func
13 2
View Code

装饰器的形成过程

 

技术分享
 1 import time
 2 
 3 def func1():
 4     print(in func1)
 5 
 6 def timer(func):
 7     def inner():
 8         start = time.time()
 9         func()
10         print(time.time() - start)
11     return inner
12 
13 func1 = timer(func1)
14 func1()
View Code

 

  装饰器—语法糖

技术分享
 1 import time
 2 def timer(func):
 3     def inner():
 4         start = time.time()
 5         func()
 6         print(time.time() - start)
 7     return inner
 8 
 9 @timer   #==> func1 = timer(func1)
10 def func1():
11     print(in func1)
12 
13 
14 func1()
View Code

  装饰器的本质:一个闭包函数

  装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展

 

  装饰器—带参数的装饰器

技术分享
 1 def timer(func):
 2     def inner(a):
 3         start = time.time()
 4         func(a)
 5         print(time.time() - start)
 6     return inner
 7 
 8 @timer
 9 def func1(a):
10     print(a)
11 
12 func1(1)
View Code

  装饰器—成功hold住所有参数的装饰器

技术分享
 1 import time
 2 def timer(func):
 3     def inner(*args,**kwargs):
 4         start = time.time()
 5         re = func(*args,**kwargs)
 6         print(time.time() - start)
 7         return re
 8     return inner
 9 
10 @timer   #==> func1 = timer(func1)
11 def func1(a,b):
12     print(in func1)
13 
14 @timer   #==> func2 = timer(func2)
15 def func2(a):
16     print(in func2 and get a:%s%(a))
17     return fun2 over
18 
19 func1(aaaaaa,bbbbbb)
20 print(func2(aaaaaa))
View Code

  装饰器—带返回值的装饰器

技术分享
 1 import time
 2 def timer(func):
 3     def inner(*args,**kwargs):
 4         start = time.time()
 5         re = func(*args,**kwargs)
 6         print(time.time() - start)
 7         return re
 8     return inner
 9 
10 @timer   #==> func1 = timer(func1)
11 def func1(a,b):
12     print(in func1)
13 
14 @timer   #==> func2 = timer(func2)
15 def func2(a):
16     print(in func2 and get a:%s%(a))
17     return fun2 over
18 
19 func1(aaaaaa,bbbbbb)
20 print(func2(aaaaaa))
View Code

开放封闭原则

  1.对扩展是开放的

    为什么要对扩展开放呢?

    我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。

  2.对修改是封闭的

    为什么要对修改封闭呢?

    就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。

  装饰器完美的遵循了这个开放封闭原则。

装饰器的主要功能和装饰器的固定结构

  装饰器的主要功能:

    在不改变函数调用方式的基础上在函数的前、后添加功能。

  装饰器的固定格式:

技术分享
1 def timer(func):
2     def inner(*args,**kwargs):
3         ‘‘‘执行函数之前要做的‘‘‘
4         re = func(*args,**kwargs)
5         ‘‘‘执行函数之后要做的‘‘‘
6         return re
7     return inner
View Code

带参数的装饰器

技术分享
 1 def outer(flag):
 2     def timer(func):
 3         def inner(*args,**kwargs):
 4             if flag:
 5                 print(‘‘‘执行函数之前要做的‘‘‘)
 6             re = func(*args,**kwargs)
 7             if flag:
 8                 print(‘‘‘执行函数之后要做的‘‘‘)
 9             return re
10         return inner
11     return timer
12 
13 @outer(False)
14 def func():
15     print(111)
16 
17 func()
View Code

多个装饰器装饰同一个函数

技术分享
 1 def wrapper1(func):
 2     def inner():
 3         print(wrapper1 ,before func)
 4         func()
 5         print(wrapper1 ,after func)
 6     return inner
 7 
 8 def wrapper2(func):
 9     def inner():
10         print(wrapper2 ,before func)
11         func()
12         print(wrapper2 ,after func)
13     return inner
14 
15 @wrapper2
16 @wrapper1
17 def f():
18     print(in f)
19 
20 f()
View Code

 

以上是关于14 Python 装饰器的主要内容,如果未能解决你的问题,请参考以下文章

14 Python 装饰器

18 12 14 python提高 装饰器

Python面向对象学习之八,装饰器

python-day14--带参数的装饰器+多个装饰器装饰同一个函数

如何在python中使用条件装饰器?

python学习进度14(装饰器)