装饰器的形成过程

假如你要写一个计算函数执行时间的函数,代码如下:

 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()

唯一碍眼的那句话就是还要在做一次赋值调用,你觉得碍眼,python的开发者也觉得碍眼,所以就为我们提供了一句语法来解决这个问题!

 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()

到这里,我们可以简单的总结一下:

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

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

还有最后一个问题要解决,刚刚我们讨论的装饰器都是装饰不带参数的函数,现在要装饰一个带参数的函数怎么办呢?

 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)
13
14 装饰器——带参数的装饰器

其实装饰带参的函数并不是什么难事,但假如你有两个函数,需要传递的参数不一样呢?

 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'))

现在参数的问题已经完美的解决了,可是如果你的函数是有返回值的呢?

 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   #==> func2 = timer(func2)
11 def func2(a):
12     print('in func2 and get a:%s'%(a))
13     return 'fun2 over'
14
15 func2('aaaaaa')
16 print(func2('aaaaaa'))

刚刚那个装饰器已经非常完美了,但是正常我们情况下查看函数的一些信息的方法在此处都会失效

1 1 def index():
2 2     '''这是一个主页信息'''
3 3     print('from index')
4 4
5 5 print(index.__doc__)    #查看函数注释的方法
6 6 print(index.__name__)   #查看函数名的方

为了不让他们失效,我们还要在装饰器上加上一点来完善它:

 1 from functools import wraps
 2
 3 def deco(func):
 4     @wraps(func) #加在最内层函数正上方
 5     def wrapper(*args,**kwargs):
 6         return func(*args,**kwargs)
 7     return wrapper
 8
 9 @deco
10 def index():
11     '''哈哈哈哈'''
12     print('from index')
13
14 print(index.__doc__)
15 print(index.__name__)

开放封闭原则

  1.对扩展是开放的

    为什么要对扩展开放呢?

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

  2.对修改是封闭的

    为什么要对修改封闭呢?

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

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

 

装饰器的主要功能:

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

装饰器的固定格式:

#普通版本
def timer(func):def inner(*args,**kwargs):'''执行函数之前要做的'''re = func(*args,**kwargs)'''执行函数之后要做的'''return rereturn inner
# wraps版本
from functools import wrapsdef deco(func):@wraps(func) #加在最内层函数正上方def wrapper(*args,**kwargs):return func(*args,**kwargs)return wrapper

带参数的装饰器

可以实现函数是否执行

 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()

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

有些时候,我们也会用到多个装饰器装饰同一个函数的情况。

 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()

转载于:https://www.cnblogs.com/ppf3678/p/10304699.html

python三大神器之装饰器相关推荐

  1. python三层装饰器-python三大神器===》装饰器

    1.认识装饰器 如果你经常看我的博客,你已经学会了python的前两大"神器'(迭代器,生成器),那么什么是装饰器呢?就如字面意义装饰器是对某个事物(通常指函数)进行装饰,让其在不修改任何内 ...

  2. python三大神器===》装饰器

    1.认识装饰器 如果你经常看我的博客,你已经学会了python的前两大'神器'(迭代器,生成器),那么什么是装饰器呢?就如字面意义装饰器是对某个事物(通常指函数)进行装饰,让其在不修改任何内部代码的情 ...

  3. 什么是装饰器 python_python三大神器===》装饰器

    1.认识装饰器 如果你经常看我的博客,你已经学会了python的前两大'神器'(迭代器,生成器),那么什么是装饰器呢?就如字面意义装饰器是对某个事物(通常指函数)进行装饰,让其在不修改任何内部代码的情 ...

  4. python三大器之一——装饰器详解

    python的三大器指的是:装饰器.迭代器.生成器,下面就装饰器整理一下从各种资源收获的对装饰器的理解. 1.理解装饰器之前先要理解函数引用的概念 def func():print("hel ...

  5. python求助神器_【python从零开始(被称之为神器的装饰器)】- 环球网校

    [摘要]假设今天我中了500万,我打算在北京买一个厕所,厕所的功能就是大小便,我觉得需要加点什么,给厕所改造一下,但是要保证厕所的功能,添加一面镜子,再来个热水器,装个喷头.一个三星级厕所打造成功.这 ...

  6. itext生成pdf paragraph 自动换行_reportlab高级制作多格式PDF和python的class和装饰器复习

    1 说明 1.1 reportlab高级制作多格式PDF:即包含文字.表格.柱状图. 1.2 复习python的class和装饰器的高级基础知识. 1.3 列表转换字符串.读取txt文件等python ...

  7. python类装饰器详解-Python类中的装饰器在当前类中的声明与调用详解

    我的Python环境:3.7 在Python类里声明一个装饰器,并在这个类里调用这个装饰器. 代码如下: class Test(): xx = False def __init__(self): pa ...

  8. 第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解

    第7.26节 Python中的@property装饰器定义属性访问方法getter.setter.deleter 详解 一.    引言 Python中的装饰器在前面接触过,老猿还没有深入展开介绍装饰 ...

  9. python return用法_初学Python要了解什么 装饰器知识汇总有哪些

    初学Python要了解什么?装饰器知识汇总有哪些?在Python学习过程中,有多种方法对函数和类进行加工,相对于其它方式,装饰器语法简单,代码可读性高.因此,装饰器在Python项目中有广泛的应用,比 ...

最新文章

  1. 从互联网大厂裸辞 500 天后,我发生哪些变化?
  2. DotNetCore跨平台~xUnit和测试报告
  3. java如何写对象配置文件,Java 读写Properties配置文件详解
  4. 吐血整理 《计算机网络 五层协议之物理层(上)》
  5. Spark1.4启动spark-shell时initializing失败
  6. 找出所有支持UI5的BSP application
  7. 【重温经典算法之二】快速排序
  8. python—列表、字典生成式
  9. Java从键盘获取输入各种类型的数据方式
  10. python 输入华氏温度f_如何用 python编写华氏摄氏度的相互转换?
  11. C++ 的 allocator类 提供类型化的内存分配以及对象的分配和撤销
  12. JavaScript运算符的概述分类及其优先级
  13. 11.8 scrum report
  14. Java生成随机常用汉字或姓名
  15. 工业控制pc是微型计算机,微型计算机工业控制.doc
  16. python实现语音机器人
  17. mysql5.1不支持中文,MySQL_MySQL5.1的中文支持的一个改进, MySQL 5.1的中文支持的一个改 - phpStudy...
  18. img、link、html使用样式
  19. 【榆钱】Cantor表C语言题解
  20. 中地恒达水库大坝监测,倾斜监测系统(Guard-QJ)

热门文章

  1. php判断多维数组的技巧
  2. 转:Oracle中的日期和字符串互相转换
  3. j2recover----最强大的jfs2文件恢复工具
  4. 从零开始学建站-主机篇
  5. 网络风行者(KSpider)的规则体系结构
  6. 实现linux作为server时与windows间的数据同步
  7. 整合大数据价值最大化的三个关键因素
  8. 这些技术人棒棒哒!BingoDay2017获奖名单新鲜出炉~~~
  9. SQL触发器实例(上)
  10. NIO Socket编程实例