十九、python沉淀之路--装饰器
一、实现装饰器的预备知识
装饰器 = 高阶函数 + 函数嵌套 + 闭包
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沉淀之路--装饰器相关推荐
- Python学习之路-装饰器生成器正则表达式
装饰器 通俗的讲,装饰器就是在不改变源代码基础上,给源代码增加新功能. 不改变函数的源代码.调用方式.返回值等,给函数增加新功能. 经典案例:登录装饰器, def login_decorator(fu ...
- Python学习之路--装饰器
三元运算 变量 = 条件返回True的结果 if 条件 else 条件返回False ,用于简单 import time time.time() 1970年至今多少秒 time.sleep()暂时休眠 ...
- Python学习之路——装饰器
开放封闭原则:不改变调用方式与源代码上增加功能 ''' 1.不能修改被装饰对象(函数)的源代码(封闭) 2.不能更改被修饰对象(函数)的调用方式,且能达到增加功能的效果(开放) ''' View Co ...
- python类装饰器详解-Python类中的装饰器在当前类中的声明与调用详解
我的Python环境:3.7 在Python类里声明一个装饰器,并在这个类里调用这个装饰器. 代码如下: class Test(): xx = False def __init__(self): pa ...
- 第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解
第7.26节 Python中的@property装饰器定义属性访问方法getter.setter.deleter 详解 一. 引言 Python中的装饰器在前面接触过,老猿还没有深入展开介绍装饰 ...
- 十九. Python基础(19)--异常
十九. Python基础(19)--异常 1 ● 捕获异常 if VS异常处理: if是预防异常出现, 异常处理是处理异常出现 异常处理一般格式: try: <...............&g ...
- python return用法_初学Python要了解什么 装饰器知识汇总有哪些
初学Python要了解什么?装饰器知识汇总有哪些?在Python学习过程中,有多种方法对函数和类进行加工,相对于其它方式,装饰器语法简单,代码可读性高.因此,装饰器在Python项目中有广泛的应用,比 ...
- python log函数_python装饰器的使用
1. 装饰者模式 装饰者模式是常用的软件设计模式之一.通过此设计模式,我们能够在不修改任何底层代码情况下,给已有对象赋予新的职责.python中可以用装饰器简单地实现装饰者模式. 1.1 将函数作为参 ...
- [转载] Python学习笔记——用装饰器decorator和Memoization记忆化提高效率,原理讲清楚了
参考链接: 在Python中使用装饰器进行记忆 Python学习笔记--用装饰器decorator和Memoization记忆化提高效率 装饰器Memoization记忆化运用`functools`中 ...
- itext生成pdf paragraph 自动换行_reportlab高级制作多格式PDF和python的class和装饰器复习
1 说明 1.1 reportlab高级制作多格式PDF:即包含文字.表格.柱状图. 1.2 复习python的class和装饰器的高级基础知识. 1.3 列表转换字符串.读取txt文件等python ...
最新文章
- SQL视频总结(2)
- python hibernate_将Java/MVC/Hibernate webapp移植到Python
- 【EventBus】EventBus 源码解析 ( 事件发送 | 线程池中执行订阅方法 )
- pl/sql函数学习
- 从内存中加载并运行exe(两种方法)
- C语言文件操作 fopen, fclose, mkdir(打开关闭文件,建文件夹,判断文件是否存在可读或可写)
- github unity 图片切换效果_CSS3图片模糊切换效果
- MongoDB 字段拼接 $concat(aggregation)
- python 输入输出转web_云计算开发学习笔记:Python3 输入和输出方式
- 【Flink】Flink 实现 AT_LEAST_ONCE EXACTLY_ONCE 案例
- git rebase 的使用
- idea module取得是parent的文件路径_React(或使用TS)中样式混乱解决方案 *.module.less...
- JS获取屏幕的宽度、高度
- jabber服务器_最近JavaScript Jabber播客-Microsoft(而非Microsoft)和Web
- 孤独求败:美国海军邀黑客“黑掉军舰”
- 【ct107d】独立键盘
- PyTorch深度学习入门笔记(五)Transforms的使用
- 关于MacPorts
- python刷弹幕_每个大主播都是满屏弹幕,怎么做到的?Python实战无限刷弹幕!
- GBase 8s的高可用1-HAC(双机高性能实时数据复制)高可用方案