python3装饰器例子_python 装饰器(三):装饰器实例(一)

示例 7-15 定义了一个装饰器,它会在每次调用被装饰的函数时计时,然后把经过的时间、传入的参数和调用的结果打印出来。

示例 7-15 一个简单的装饰器,输出函数的运行时间

importtimedefclock(func):def clocked(*args): #➊

t0 =time.perf_counter()

result= func(*args) #➋

elapsed = time.perf_counter() -t0

name= func.__name__arg_str= ','.join(repr(arg) for arg inargs)print('[%0.8fs] %s(%s) -> %r' %(elapsed, name, arg_str, result))returnresultreturn clocked #➌

❶ 定义内部函数 clocked,它接受任意个定位参数。

❷ 这行代码可用,是因为 clocked 的闭包中包含自由变量 func。

❸ 返回内部函数,取代被装饰的函数。示例 7-16 演示了 clock 装饰器的用法。

示例 7-16 使用 clock 装饰器

#clockdeco_demo.py

importtimefrom clockdeco importclock

@clockdefsnooze(seconds):

time.sleep(seconds)

@clockdeffactorial(n):return 1 if n < 2 else n*factorial(n-1)if __name__=='__main__':print('*' * 40, 'Calling snooze(.123)')

snooze(.123)print('*' * 40, 'Calling factorial(6)')print('6! =', factorial(6))

运行示例 7-16 得到的输出如下:

$ python3 clockdeco_demo.py**************************************** Calling snooze(123)

[0.12405610s] snooze(.123) ->None**************************************** Calling factorial(6)

[0.00000191s] factorial(1) -> 1[0.00004911s] factorial(2) -> 2[0.00008488s] factorial(3) -> 6[0.00013208s] factorial(4) -> 24[0.00019193s] factorial(5) -> 120[0.00026107s] factorial(6) -> 720

6! = 720

工作原理

记得吗,如下代码

@clockdeffactorial(n):return 1 if n < 2 else n*factorial(n-1)

其实等价于:

deffactorial(n):return 1 if n < 2 else n*factorial(n-1)

factorial= clock(factorial)

因此,在两个示例中,factorial 会作为 func 参数传给 clock(参见示例 7-15)。然后, clock 函数会返回 clocked 函数,Python 解释器在背后会把 clocked 赋值给 factorial。

其实,导入clockdeco_demo 模块后查看 factorial 的 __name__ 属性,会得到如下结果:

>>> importclockdeco_demo>>> clockdeco_demo.factorial.__name__

'clocked'

>>>

所以,现在 factorial 保存的是 clocked 函数的引用。自此之后,每次调用 factorial(n),执行的都是 clocked(n)。clocked 大致做了下面几件事。

(1) 记录初始时间 t0。

(2) 调用原来的 factorial 函数,保存结果。

(3) 计算经过的时间。

(4) 格式化收集的数据,然后打印出来。

(5) 返回第 2 步保存的结果。

这是装饰器的典型行为:把被装饰的函数替换成新函数,二者接受相同的参数,而且(通常)返回被装饰的函数本该返回的值,同时还会做些额外操作。

示例 7-15 中实现的 clock 装饰器有几个缺点:不支持关键字参数,而且遮盖了被装饰函数的 __name__ 和 __doc__ 属性。示例 7-17 使用

functools.wraps 装饰器把相关的属性从 func 复制到 clocked 中。此外,这个新版还能正确处理关键字参数。

示例 7-17 改进后的 clock 装饰器

#clockdeco2.py

importtimeimportfunctoolsdefclock(func):

@functools.wraps(func)def clocked(*args, **kwargs):

t0=time.time()

result= func(*args, **kwargs)

elapsed= time.time() -t0

name= func.__name__arg_lst=[]ifargs:

arg_lst.append(','.join(repr(arg) for arg inargs))ifkwargs:

pairs= ['%s=%r' % (k, w) for k, w insorted(kwargs.items())]

arg_lst.append(','.join(pairs))

arg_str= ','.join(arg_lst)print('[%0.8fs] %s(%s) -> %r' %(elapsed, name, arg_str, result))returnresultreturn clocked

functools.wraps 只是标准库中拿来即用的装饰器之一。下一节将介绍 functools 模块中最让人印象深刻的两个装饰器:lru_cache 和singledispatch。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/261826.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《c专家编程》笔记--define和typedef的区别

#include <stdio.h> #define peach int typedef int banana;int main(void){unsigned peach a;unsigned banana b;return 0; } 上面的代码中&#xff0c; unsigned banana b; 该行编译会出现错误。 因为typedef是一种彻底的“封装”类型&#xff0c;而#define只是简单的文…

ExtJs6 Desktop Demo 修改测试

一直用Extjs4&#xff0c; extjs6 的变化较大&#xff0c;这几天有兴趣研究一下&#xff0c;把自带的Demo的desktop做了些修改&#xff0c; 1.首先下载安装sencha cmd 2.然后 需要生成新项目 用sencha cmd 命令如下&#xff1a; sencha -sdk E:\ext-6.0.0 generate app linb…

包含html语言的超链接标记的网页_零基础入门 HTML 的 8 分钟极简教程

在今天&#xff0c;前端工程师已经成为研发体系中的重要岗位之一。可是与此相对的是&#xff0c;极少大学的计算机专业愿意开设前端课程&#xff0c;大部分前端工程师的知识&#xff0c;也都是在实践和工作中不断学习的。最近收到很多同学的后台留言&#xff0c;说希望多推出一…

验证dropdownlist必选

假定dropdownlist: <asp:dropdownlist id"ddListNewsType" runat"server"><asp:ListItem Value"请选择类别" Selected"True">请选择类别</asp:ListItem><asp:ListItem Value"新闻中心">新闻中心<…

kotlin读取html,kotlin 使用skrape {it}从html获取数据 - 糯米PHP

查看语法&#xff0c;我假设您使用的是0.6.0版。您必须使用更特定的CSS选择器。data class MyScrapedData(val userName: String,val link: String)fun main() {val githubUserData skrape {url "http://www.website"extract {MyScrapedData(userName el("di…

C++函数默认值的用法

C函数默认值的用法 在C中&#xff0c;函数允许提供一个默认值。这样&#xff0c;当函数被调用时如果没有提供这些参数的值&#xff0c;编译器会自动使用默认值。示例代码如下&#xff1a; #include <iostream>// 函数声明&#xff0c;指定默认参数 void myFunction(int…

c++单链表【构造函数、运算符重载、析构函数、增删查改等】

c中的单向链表写法&#xff1a;实现增删查改、构造函数、运算符重载、析构函数等。建立头文件SList.h#pragma oncetypedef int DataType; //SList要访问SListNode&#xff0c;可以通过友元函数实现&#xff0c;友元函数在被访问的类中 class SListNode {friend class SList;//友…

mongodb模糊查询_AWS 回击了!推出兼容 MongoDB 的 DocumentDB

2018 年 10 月&#xff0c;MongoDB 将其开源许可证从 GNU AGPLv3 切换到 Server Side Public License(SSPL)&#xff0c;并明确指出之所以会更改开源协议是因为部分云计算公司在使用 MongoDB 的时候没有遵循其开源协议。2019 年 1 月 9 日&#xff0c;AWS 宣布推出 Amazon Docu…

MyEclipse6.5与Perforce的集成

perforce插件下载地址http://www.perforce.com/downloads/http/p4-wsad/install/3.4 转载于:https://www.cnblogs.com/xinzhuangzi/archive/2010/08/29/4100531.html

琴岛学院计算机应用技术,我院计算机工程系成功晋级“中国高校计算机大赛-网络技术挑战赛”全国总决赛...

2017年7月22日&#xff0c;由教育部高等学校计算机类专业教学指导委员会、教育部高等学校软件工程专业教学指导委员会、教育部高等学校大学计算机课程教学指导委员会和全国高等学校计算机教育研究会联合主办的“中国高校计算机大赛”首届网络技术挑战赛于济南大学举办。青岛理工…

C语言宏定义##连接符和#符的使用及其它宏定义注意事项

C语言中如何使用宏C&#xff08;和C&#xff09;中的宏&#xff08;Macro&#xff09;属于编译器预处理的范畴&#xff0c;属于编译期概念&#xff08;而非运行期概念&#xff09;。下面对常遇到的宏的使用问题做了简单总结。 关于#和## 在C语言的宏中&#xff0c;#的功能是将其…

Android L 的 Tint(着色)

Tint 是什么&#xff1f; Tint 翻译为着色。 着色&#xff0c;着什么色呢&#xff0c;和背景有关&#xff1f;当然是着背景的色。当我们开发 App 的时候&#xff0c;如果使用了 Theme.AppCompat 主题的时候&#xff0c;会发现 ActionBar 或者 Toolbar 及相应的控件的颜色会相应…

python 调用函数 开销_Python函数调用非常慢

这主要是为了确保我的方法是正确的,但我的基本问题是,如果我需要访问函数,那么检查函数外部是否值得.我知道,我知道,过早优化,但在很多情况下,它在函数调用中放置一个if语句以确定是否需要运行其余代码,或者将它放在函数调用之前.换句话说,它不会以任何方式做到这一点.现在,所有…

机房收费系统讨论

在假期快要结束的时候,我们大家一起讨论了各自的机房收费系统.轮流的看了每个人的作品.我们是分两个组看得. 说说看这次作品的感受吧. 大家作品都做得很认真.由于都是第一次做作品,而且还是第一次自己独立的完成一个较大的作品. 基本功能大家可是说是都实现了.我个人的作品现在…

《从零开始学Swift》学习笔记(Day 66)——Cocoa Touch设计模式及应用之通知机制...

原创文章&#xff0c;欢迎转载。转载请注明&#xff1a;关东升的博客 通知&#xff08;Notification&#xff09;机制是基于观察者&#xff08;Observer&#xff09;模式也叫发布/订阅&#xff08;Publish/Subscribe&#xff09;模式&#xff0c;是 MVC&#xff08;模型-视图-控…

医学计算机应用研究的意义,医学图像感兴趣区域的自动提取-计算机应用研究.PDF...

医学图像感兴趣区域的自动提取-计算机应用研究第 12 期 何 楚等: 医学图像感兴趣区域的自动提取 157 医学图像感兴趣区域的自动提取*何 楚, 彭文敏, 李吉星, 廖孟扬( 武汉大学 电子信息学院, 湖北 武汉 430072)摘 要: 针对医学图像归档与通信系统通过视频采集和胶片扫描产生的海…

JUnit3 一次运行多个测试类和进行多次重复测试:使用测试套件和RepeatedTest

测试套件 如果测试类写到很多&#xff0c;每次要进行测试&#xff0c;难道要重新点击每一个测试类来运行&#xff1f;如果有200个测试类要测试呢&#xff1f; 为了解决这个问题&#xff0c;引入了测试套件&#xff08;TestSuite&#xff09;。 通过将多个测试放入套件中&#x…

DataGridView控件初始化,添加删除行(不绑定数据库)

转载&#xff1a; http://blog.163.com/zjlovety126/blog/static/2241862420106128264300/ 也不知道是否该应用这个控件&#xff0c;不过也想不出该用其他什么控件&#xff0c;关键是俺比较菜没什么经验。 要求是这样的&#xff0c;用户一次添加一个任务&#xff0c;这个任务有…

mysql 不同分区 同时insert_Mysql分区表的原理和优缺点

分区表的原理分区表是由多个相关的底层表实现&#xff0c;这些底层表也是由句柄对象表示&#xff0c;所以我们也可以直接访问各个分区&#xff0c;存储引擎管理分区的各个底层表和管理普通表一样(所有的底层表都必须使用相同的存储引擎)&#xff0c;分区表的索引只是在各个底层…

计算机应用 范文,计算机应用基础(范文).doc

第 PAGE \* Arabic 1 页计算机应用基础(范文)PAGE计算机应用基础5一、单选题1、第一台电子计算机是1946年在美国研制成功的&#xff0c;该机的英文缩写名是_ A&#xff1a;ENIAC _____。2、关于计算机的分类方法有多种&#xff0c;下列选项中不属于按计算机处理数据的方式进行分…