1. 装饰器的定义

就是给已有函数增加额外功能的函数,它本质上就是一个闭包函数。

装饰器的功能特点: 不修改已有函数的源代码

不修改已有函数的调用方式

给已有函数增加额外的功能

闭包和装饰器的区分:

如果闭包函数的参数有且只有一个,并且是函数类型,那么这个闭包函数称之为装饰器。

写代码要遵循开放封闭原则,它规定已经实现的功能代码不允许被修改,但可以被扩展。

2. 装饰器的示例代码

# 定义装饰器def decorator(func): def inner(): # 在内部函数里面对已有函数进行装饰 print('已添加登录认证') func() return innerdef comment(): print('发表评论')# 调用装饰器对已有函数进行装饰,左边的comment=innercomment = decorator(comment)# 调用方式不变comment()1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

201

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

3. 装饰器的语法糖写法

如果有多个函数都需要添加登录验证的功能,每次都需要编写func = decorator(func)这样代码对已有函数进行装饰,这种做法还是比较麻烦。

Python给提供了一个装饰函数更加简单的写法,那就是语法糖,语法糖的书写格式是: @装饰器名字,通过语法糖的方式也可以完成对已有函数的装饰 # 定义装饰器def decorator(func): def inner(): # 在内部函数里面对已有函数进行装饰 print('已添加登录认证') func() return inner@decorator # comment = decorator(comment) 装饰器语法糖对该代码进行了封装 左边comment=innerdef comment(): print('发表评论')# 调用方式不变comment()1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

181

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

4. 装饰器的执行时机

当 当前模块加载完成以后,装饰器会立即执行,对已有函数进行装饰。

# 定义装饰器def decorator(func): print('装饰器执行了') def inner(): # 在内部函数里面对已有函数进行装饰 print('已添加登录认证') func() return inner@decorator # comment = decorator(comment) 装饰器语法糖对该代码进行了封装 左边comment=innerdef comment(): print('发表评论')1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

161

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

运行结果: 装饰器执行了11

5. 装饰器的使用

5.1 装饰器的使用场景 函数执行时间的统计

输出日志信息

5.2 装饰器实现已有函数执行时间的统计

import timedef decorator(func): def inner(): # 获取时间距离1970-1-1 0:0:1的时间差 begin = time.time() func() end = time.time() result = end - begin print(f'函数执行完成耗时:{result}') return inner@decoratordef work(): for i in range(10000): print(i)work()1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

231

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

6. 通用装饰器的使用

通用装饰器:可以装饰任意类型的函数

使用装饰器装饰已有函数的时候,内部函数的类型和要装饰的已有函数的类型保持一致

6.1 装饰带有参数的函数 def decorator(func): def inner(num1, num2): print('正在努力执行加法计算') func(num1, num2) return inner@decoratordef add_num(num1, num2): result = num1 + num2 print(f'结果为:{result}')add_num(1, 2)1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

161

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

6.2 装饰带有参数、返回值的函数

def decorator(func): def inner(num1, num2): print('正在努力执行加法计算') num = func(num1, num2) return num return inner@decoratordef add_num(num1, num2): result = num1 + num2 return resultresult = add_num(1, 2)print(f'结果为:{result}')1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

181

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

6.3 装饰带有不定长参数、返回值的函数 def decorator(func): def inner(*args, **kwargs): print('正在努力执行加法计算') # *args:把元组里面的每一个元素,按照位置参数的方式进行传参 # **kwargs:把字典里面的每一个键值对,按照关键字的方式进行传参 num = func(*args, **kwargs) return num return inner@decoratordef add_num(*args, **kwargs): result = 0 for value in args: result += value for value in kwargs.values(): result += value return resultresult = add_num(1, 2, a=3)print(f'结果为:{result}')1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

241

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

7. 多个装饰器的使用

多个装饰器的装饰过程:由内到外的一个装饰过程,先执行内部的装饰器,在执行外部的装饰器。

def make_div(func): print('make_div装饰器执行了') def inner(): result = '

' + func() + '

' return result return innerdef make_p(func): print('make_p装饰器执行了') def inner(): result = '

' + func() + '

' return result return inner# 原理剖析:content = make_div(make_p(content))# 分布拆解:content = make_p(content),内部装饰器完成,content = make_p.inner# content = make_div(make_p.inner)@make_div@make_pdef content(): return '人生苦短,我用python'c = content()print(c)1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

321

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32 make_p装饰器执行了make_div装饰器执行了

人生苦短,我用python

1

2

31

2

3

8. 带有参数的装饰器

带有参数的装饰器就是使用装饰器装饰函数的时候可以传入指定参数,语法格式: @装饰器(参数,…)

使用带有参数的装饰器,其实是在装饰器外面又包裹了一个函数,使用该函数接收参数,返回是装饰器,因为 @ 符号需要配合装饰器实例使用。

def return_decorator(flag): # 装饰器只能接收一个参数并且是函数类型 def decorator(func): def inner(a, b): if flag == '+': print('正在努力执行加法计算') elif flag == '-': print('正在努力执行减法计算') func(a, b) return inner # 当调用函数的时候可以返回一个装饰器decorator return decorator@return_decorator('+') # decorator = return_decorator('+'), @decorator => add_num = decorator(add_num)def add_num(a, b): result = a + b print(result)@return_decorator('-')def sub_num(a, b): result = a - b print(result)add_num(1, 2)sub_num(1, 2)1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

311

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31 正在努力执行加法计算3正在努力执行减法计算-11

2

3

41

2

3

4

9. 类装饰器的使用

类装饰器:使用类装饰已有函数

class MyDecorator(object): def __init__(self, func): self.__func = func # 实现__call__方法,表示对象是一个可调用对象,可以像调用函数一样进行调用 def __call__(self, *args, **kwargs): # 对已有函数进行封装 print('马上就有下班啦') self.__func()@MyDecorator # @MyDecorator => show = MyDecorator(show)def show(): print('快要下雪啦')# 执行show,就相当于执行MyDecorator类创建的实例对象,show() => 对象()show()1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

191

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19 马上就有下班啦快要下雪啦1

21

2

扩展:

函数之所以能够调用,是因为函数内部实现了 __call__ 方法

10. 应用场景

收集函数的操作或错误日志记录

验证函数的使用权限

计算函数的运行时间

在ORM/DB模型操作时,通过属性方法动态地获取关联的数据

函数数据的缓存

定制函数的输入和输出(序列化和反序列化)

python中修饰器的优点和作用_Python装饰器(你想知道的这里都有)相关推荐

  1. python中修饰器的优点和作用_python 装饰器

    1. 装饰器装饰器其实是一个函数,作用是装饰其他函数 装饰器的特点:1. 不改变被装饰的函数的源代码的情况下添加函数的功能 2. 不改变被装饰的函数的调用方式 装饰器的组成方式:高阶函数+嵌套函数 1 ...

  2. python的装饰器迭代器与生成器_详解python中的生成器、迭代器、闭包、装饰器

    迭代是访问集合元素的一种方式.迭代器是一个可以记住遍历的位置的对象.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退. 1|1可迭代对象 以直接作用于 for ...

  3. python中装饰器的作用_Python装饰器详解,详细介绍它的应用场景

    装饰器的应用场景附加功能 数据的清理或添加:函数参数类型验证 @require_ints 类似请求前拦截数据格式转换 将函数返回字典改为 JSON/YAML 类似响应后篡改为函数提供额外的数据 moc ...

  4. python装饰器函数执行后日志_python 装饰器理解

    在理解装饰器之前,先应该对闭包有个概念:所谓闭包,就是将组成函数的语句和这些语句的执行环境打包在一起时得到的对象,它的主要作用是封存上下文.这一特性可以巧妙的被用于现有函数的包装,从而为现有函数添加功 ...

  5. python中修饰器的优点和作用_Python入门基础教程之装饰器

    Python装饰器的定义:在代码运行期间在不改变原函数定义的基础上,动态给该函数增加功能的方式称之为装饰器(Decorator) 装饰器的优点和用途: 1. 抽离出大量函数中与函数功能本身无关的的雷同 ...

  6. python装饰器原理wraps(method)(self)_python装饰器中@wraps作用--修复被装饰后的函数名等属性的改变...

    Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),为了不影响,Python的functools包中提供了一个叫wraps的de ...

  7. python中的迭代器,生成器,闭包,装饰器,@property

    一.迭代器 迭代器在Python中无处不在.它们在for循环,理解,生成器等中优雅地实现,但却隐藏在眼皮底下. Python中的Iterator只是一个可以迭代的对象.一个将返回数据的对象,一次返回一 ...

  8. python中面向切片编程(AOP)和装饰器

    @函数名(类的描述符)相当于fuc = decorator(fuc) 装饰器: def deco(fuc):print('============')return fuc @deco def foo( ...

  9. Python 中的闭包、匿名函数、decorator 装饰器与python的偏函数

    Python中的闭包 def calc_sum(lst):def lazy_sum():return sum(lst)return lazy_sum 像这种内层函数引用了外层函数的变量(参数也算变量) ...

最新文章

  1. LayoutInflater的inflate函数用法详解
  2. 翻译:如何用Cocos2d来开发简单的IPhone游戏教程
  3. 北斗导航 | NED(北东地)转ECEF(地心地固)或ECEF转NED(Matlab源代码)
  4. 数学--数论--最小公倍数+最大公约数
  5. Fiddler (一) 教程(Web调试工具)
  6. ASP.NET教程5
  7. linux内核那些事之用户空间管理
  8. eclipse web项目页面显示404_404 Not Found错误页面是什么?
  9. 【bzoj4709】[Jsoi2011]柠檬 斜率优化
  10. Unity2018新功能抢鲜 | ShaderGraph入门教程
  11. mysql卡住如何定位_MySQL 5.7中如何定位DDL被阻塞的问题
  12. 企业信息化与BI系统建设规划
  13. 计算机主机运行显示屏黑屏,电脑开机黑屏_电脑启动显示器黑屏的原因和检修-太平洋IT百科...
  14. 5G 网络的移动性管理上下文对比介绍
  15. nginx代理frps后出现 http proxy request error: no such domain
  16. 得链表者得天下(上)
  17. 快速入门开发实现订单类图片识别结果抽象解析
  18. Python输出16进制不带0x补零,整数转16进制,字符串转16进制
  19. iPhone微信语音导出
  20. c 语言头文件seqlsit,2020-10-24 RNAseq 从fq开始分析全流程

热门文章

  1. 俞敏洪+摆脱恐惧+世界想让你做一个平凡的人、你信了吗
  2. 影像组学视频学习笔记(43)-标准差、标准误及95%置信区间CI、Li‘s have a solution and plan.
  3. 服务器安装使用rstudio-server
  4. BST AVL 红黑树 B B+树
  5. 数字图像处理- 3.4 空间滤波 and 3.5 平滑空间滤波器
  6. 专升本考试计算机知识小抄,大学考试让带“小抄”,学生却说不如闭卷…原因亮了!...
  7. android 固定底部,如何将view固定在屏幕底部?
  8. linux yum安装mysql 5.6_linux yum安装MySQL5.6
  9. python for 循环中使用 remove 删除列表中的元素
  10. 手机CNN网络模型--MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications