一、实现装饰器的预备知识

装饰器 = 高阶函数 + 函数嵌套 + 闭包

1、高价函数定义:

1.函数接收的参数是一个函数名
    2.函数的返回值是一个函数名
    3.满足上述条件任意一个,都可称之为高阶函数

例1:铺垫

 1 import time
 2 #例1
 3 def fn():
 4     print('这是被调用函数')
 5     time.sleep(2)
 6
 7 def test(func):
 8     print('高阶函数将要开始运行')
 9     start_time = time.time()
10     func()
11     end_time = time.time()
12     print('被调用函数的运行时间%s'%(end_time - start_time))
13
14 test(fn)

View Code

例2

 1 #例2
 2 import time
 3 def fn():
 4     print('这是被调用函数')
 5     time.sleep(2)
 6 def test(func):
 7     print('正在执行高阶函数')
 8     return func
 9 #第一种调用
10 f = test(fn)
11 print(f)
12 f()
13
14 ## 第二种调用,升级版 :将调用函数test(func)的返回值赋值给一个与被调用函数fn()同名的变量fn,最后实现的效果就是
15                       #(1)不改变被调用函数fn()的源代码
16                       #(2) 不改变被调用函数fn()的调用方式
17 fn = test(fn)
18 print(fn)
19 fn()

View Code

1 正在执行高阶函数
2 <function fn at 0x0000017065C999D8>
3 这是被调用函数
4 正在执行高阶函数
5 <function fn at 0x0000017065C999D8>
6 这是被调用函数

View Code

升级版 :将调用函数test(func)的返回值赋值给一个与被调用函数fn()同名的变量fn,最后实现的效果就是                      (1)不改变被调用函数fn()的源代码                      (2) 不改变被调用函数fn()的调用方式

例3  这种情况出现的结果是 多运行了一行

 1 # 例3
 2 import time
 3 def fn():
 4     print('这是被调用函数')
 5     time.sleep(2)
 6
 7 def test(func):
 8     print('开始执行调用函数')
 9     start_time = time.time()
10     func()
11     end_time = time.time()
12     return func      # 这种情况出现的结果是 多运行了一行
13
14 fn = test(fn)
15 fn()

View Code

1 开始执行调用函数
2 这是被调用函数
3 这是被调用函数

View Code

例4

 1 #例4
 2 def fn():
 3     print('这是被调用函数')
 4 def test(func):
 5     print('正在执行高阶函数')
 6     res = func()
 7     print('被调用函数执行完毕')
 8     return res
 9
10 fn = test(fn)
11 # fn()     # 报错  :TypeError: 'NoneType' object is not callable

View Code

1 正在执行高阶函数
2 这是被调用函数
3 被调用函数执行完毕

View Code

即使赋了一个值,也还是解决不了多打印一行的结果。所以单层函数解决不了这个问题

高阶函数总结:
1、函数接收的参数是一个函数名
    作用:在不修改函数源代码的前提下,为函数添加新功能。
    不足:会改变函数的调用方式。
2、函数的返回值是一个函数名:
    作用:不修改函数的调用方式
    不足:不能添加新功能。

二、嵌套函数

定义:

 1 def father(name):
 2     print('%s is from father'%name)
 3     def son():
 4         print('I am BeiJing,My fahter is %s'%name)
 5         def grandson():
 6             print('I am HaiDian,My grandfather is %s'%name)
 7         grandson()
 8     son()
 9     # print(locals())
10
11 father('china')

1 china is from father
2 I am BeiJing,My fahter is china
3 I am HaiDian,My grandfather is china

详解在我的另外一篇博客里面:http://www.cnblogs.com/jianguo221/p/8984618.html

三、实现装饰器(步骤进化)(重点中的重点)

 1 #进化版############################################################3
 2 import time
 3 def outer(func):
 4     def inner():
 5         print('开始运行被测试函数')
 6         start_time = time.time()
 7         func()
 8         end_time = time.time()
 9         print('被测试函数的运行时间是:%s'%(start_time - end_time))
10     return inner
11
12 def test():
13     print('正在运行这个测试函数')
14     time.sleep(2)
15 # 慢慢实现装饰器
16 #第一种调用方式
17 f = outer(test)     #这条语句返回的就是inner的地址,即函数体
18 f()
19
20 #第二种调用方式
21 inner = outer(test)    ##这条语句返回的就是inner的地址,即函数体
22 inner()
23 #由于第二种调用方式  和 第一种调用方式实现的效果是一样的。所以就满足了 装饰器的两个条件:
24                      #(1)不改变被调用函数test()的源代码
25                      #(2) 不改变被调用函数test()的调用方式
26 #继续过度:由于第二种方式满足了装饰器调用的两个条件,就可以用  装饰器的一个 语法糖  形式来替换第二种形式,
27           #以便实现简便操作  , 即加一个  @outer  .如下面的例子
28 #加语法糖
29 #终极版###################################
30 import time
31 def outer(func):
32     def inner():
33         print('开始运行被测试函数')
34         start_time = time.time()
35         func()
36         end_time = time.time()
37         print('被测试函数的运行时间是:%s'%(start_time - end_time))
38     return inner
39 @outer
40 def test():
41     print('正在运行这个测试函数')
42     time.sleep(2)
43
44 #加了语法糖后,调用方式就简单很多,只需要这样写就好了。语法糖  @outer  就等价于  test =outer(test)
45 test()

运行结果:

1 开始运行被测试函数
2 正在运行这个测试函数
3 被测试函数的运行时间是:-2.000378370285034
4 开始运行被测试函数
5 正在运行这个测试函数
6 被测试函数的运行时间是:-2.0004947185516357
7 开始运行被测试函数
8 正在运行这个测试函数
9 被测试函数的运行时间是:-2.0002481937408447

转载于:https://www.cnblogs.com/jianguo221/p/8983729.html

十九、python沉淀之路--装饰器相关推荐

  1. Python学习之路-装饰器生成器正则表达式

    装饰器 通俗的讲,装饰器就是在不改变源代码基础上,给源代码增加新功能. 不改变函数的源代码.调用方式.返回值等,给函数增加新功能. 经典案例:登录装饰器, def login_decorator(fu ...

  2. Python学习之路--装饰器

    三元运算 变量 = 条件返回True的结果 if 条件 else 条件返回False ,用于简单 import time time.time() 1970年至今多少秒 time.sleep()暂时休眠 ...

  3. Python学习之路——装饰器

    开放封闭原则:不改变调用方式与源代码上增加功能 ''' 1.不能修改被装饰对象(函数)的源代码(封闭) 2.不能更改被修饰对象(函数)的调用方式,且能达到增加功能的效果(开放) ''' View Co ...

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

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

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

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

  6. 十九. Python基础(19)--异常

    十九. Python基础(19)--异常 1 ● 捕获异常 if VS异常处理: if是预防异常出现, 异常处理是处理异常出现 异常处理一般格式: try: <...............&g ...

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

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

  8. python log函数_python装饰器的使用

    1. 装饰者模式 装饰者模式是常用的软件设计模式之一.通过此设计模式,我们能够在不修改任何底层代码情况下,给已有对象赋予新的职责.python中可以用装饰器简单地实现装饰者模式. 1.1 将函数作为参 ...

  9. [转载] Python学习笔记——用装饰器decorator和Memoization记忆化提高效率,原理讲清楚了

    参考链接: 在Python中使用装饰器进行记忆 Python学习笔记--用装饰器decorator和Memoization记忆化提高效率 装饰器Memoization记忆化运用`functools`中 ...

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

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

最新文章

  1. SQL视频总结(2)
  2. python hibernate_将Java/MVC/Hibernate webapp移植到Python
  3. 【EventBus】EventBus 源码解析 ( 事件发送 | 线程池中执行订阅方法 )
  4. pl/sql函数学习
  5. 从内存中加载并运行exe(两种方法)
  6. C语言文件操作 fopen, fclose, mkdir(打开关闭文件,建文件夹,判断文件是否存在可读或可写)
  7. github unity 图片切换效果_CSS3图片模糊切换效果
  8. MongoDB 字段拼接 $concat(aggregation)
  9. python 输入输出转web_云计算开发学习笔记:Python3 输入和输出方式
  10. 【Flink】Flink 实现 AT_LEAST_ONCE EXACTLY_ONCE 案例
  11. git rebase 的使用
  12. idea module取得是parent的文件路径_React(或使用TS)中样式混乱解决方案 *.module.less...
  13. JS获取屏幕的宽度、高度
  14. jabber服务器_最近JavaScript Jabber播客-Microsoft(而非Microsoft)和Web
  15. 孤独求败:美国海军邀黑客“黑掉军舰”
  16. 【ct107d】独立键盘
  17. PyTorch深度学习入门笔记(五)Transforms的使用
  18. 关于MacPorts
  19. python刷弹幕_每个大主播都是满屏弹幕,怎么做到的?Python实战无限刷弹幕!
  20. GBase 8s的高可用1-HAC(双机高性能实时数据复制)高可用方案

热门文章

  1. py-R-FCN安装
  2. EMC混合云解决方案Enterprise Hybrid Cloud升级
  3. 【DIOCP开源项目】实际应用案例
  4. 【Iphone 游戏开发之一】创建视图并绘制简单图形
  5. 开源月刊(Open Source)
  6. 满足客户的需求是要有前提的!
  7. PAT A1053 Path of Equal Weight [树的DFS遍历]
  8. 基于Angular5和WebAPI的增删改查(一)
  9. 【oracle】oracle常用命令汇总
  10. 【诗和远方】一个蒟蒻的年初展望