Python装饰器举例分析
概述
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。
我们要需要一个能测试函数运行时间的decorator,可以定义如下:
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print("Run time is: %s" % (end_time - start_time))
return res
return wrapper
因为它是一个decorator,所以接受一个函数作为参数,并返回一个函数。我们要借助Python的@语法,把decorator置于函数的定义处:
@timer
def fun():
time.sleep(1)
print("This is a test")
return "OK"
运行结果就是:
This is a test
Run time is: 1.0000572204589844
OK
把@timer放在fun()处就相当于执行了语句:
fun = timer(fun)
如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,比如加上名字:
def timer(name):
def decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print("Name is: %s ; Run time is: %s" % (name, (end_time - start_time)))
return res
return wrapper
return decorator
调用及结果显示如下:
@timer("Lance#")
def fun():
time.sleep(1)
print("This is a test")
return "OK"
This is a test
Name is: Lance# ; Run time is: 1.0000572204589844
OK
和两层嵌套的decorator相比,三层嵌套的效果是这样的:
fun = timer("Lance#")(fun)
因为函数也是对象,它也有__name__等属性。
在未加装饰器之前的fun()函数,调用 fun的__name__属性结果是 'fun',但经过decorator装饰之后的函数,它们的__name__已经从原来的'fun'变成了'wrapper'
所以,需要把原始函数的__name__等属性复制到wrapper()函数中,否则,有些依赖函数签名的代码执行就会出错。
Python内置的functools.wraps就可以完成这个任务,所以,一个完整的decorator的写法如下:
import functools
def timer(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print("Run time is: %s" % (end_time - start_time))
return res
return wrapper
整体代码如下:
__Author__ = "Lance#"
# -*- coding = utf-8 -*-
import time
import functools
def timer(name):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print("Name is: %s ; Run time is: %s" % (name, (end_time - start_time)))
return res
return wrapper
return decorator
@timer("Lance#")
def fun():
time.sleep(1)
print("This is a test")
return "OK"
if __name__ == '__main__':
print(fun())
Python装饰器举例分析的更多相关文章
- [python 基础]python装饰器(一)添加functools获取原函数信息以及functools.partial分析
python装饰器学习的时候有两点需要注意一下 1,被装饰器装饰的函数取其func.__name__和func.func_doc的时候得到的不是被修饰函数的相关信息而是装饰器wrapper函数的doc ...
- Python装饰器由浅入深
装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们 ...
- python 装饰器 一篇就能讲清楚
装饰器一直是我们学习python难以理解并且纠结的问题,想要弄明白装饰器,必须理解一下函数式编程概念,并且对python中函数调用语法中的特性有所了解,使用装饰器非常简单,但是写装饰器却很复杂.为了讲 ...
- Python装饰器探险
关于python装饰器的理解和用法,推荐廖雪峰老师和这一篇博客以及知乎 以下代码均已手动敲过,看完本篇内容,包你装饰器小成! 装饰器实际上就是为了给某程序增添功能,但该程序已经上线或已经被使用,那么就 ...
- Python装饰器的通俗理解
转载:http://blog.csdn.net/u013471155 在学习Python的过程中,我相信有很多人和我一样,对Python的装饰器一直觉得很困惑,我也是困惑了好久,并通过思考和查阅才能略 ...
- python装饰器(docorator)详解
引言: 装饰器是python面向对象编程三大器之一,另外两个迭代器.生成器只是我现在还没有遇到必须使用的场景,等确实需要用到的时候,在补充资料:装饰器在某些场景真的是必要的,比如定义了一个类或者一个函 ...
- Python 装饰器学习心得
最近打算重新开始记录自己的学习过程,于是就捡起被自己废弃了一年多的博客.这篇学习笔记主要是记录近来看的有关Python装饰器的东西. 0. 什么是装饰器? 本质上来说,装饰器其实就是一个特殊功能的函数 ...
- (一)Python装饰器的通俗理解
在学习Python的过程中,我相信有很多人和我一样,对Python的装饰器一直觉得很困惑,我也是困惑了好久,并通过思考和查阅才能略有领悟,我希望以下的内容会对你有帮助,我也努力通过通俗的方式使得对Py ...
- Python 装饰器初探
Python 装饰器初探 在谈及Python的时候,装饰器一直就是道绕不过去的坎.面试的时候,也经常会被问及装饰器的相关知识.总感觉自己的理解很浅显,不够深刻.是时候做出改变,对Python的装饰器做 ...
随机推荐
- python 安装第三方包时 read timed out
记录下安装python第三方包超时报错,解决方法:(以安装numpy为例) pip install numpy 报错:raise ReadTimeoutError(self._pool, None, ...
- 网页打印样式CSS
相信大多数的前端工程师都是处理显示屏上面的设计,用到最多的计量单位就是px,但是有些时候,我们难免也会有打印的需求,比如一个电商平台的“物流配送打印单”,“打印订单”等等可能都是需要从网友上打印出来的 ...
- C++ MFC棋牌类小游戏day4
根据昨天的计划,今天开始做下面的内容. 1.鼠标点击事件 2.点击坐标进行处理.(坐标转换) 3.判断选中的位置是否有效. 4.确定选中的棋子,设置棋子的状态和棋子所在坐标的状态. 5.判断移动是否有 ...
- EF6 学习笔记(二):操练 CRUD 增删改查
EF6学习笔记总目录 ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 接上篇: EF6 学习笔记(一):Code First 方式生成数据库及初始化数据库实际操作 本篇原文链接: I ...
- 深度学习框架caffe/CNTK/Tensorflow/Theano/Torch的对比
在单GPU下,所有这些工具集都调用cuDNN,因此只要外层的计算或者内存分配差异不大其性能表现都差不多. Caffe: 1)主流工业级深度学习工具,具有出色的卷积神经网络实现.在计算机视觉领域Caff ...
- 2.DI依赖注入
一:DI Dependency Injection ,依赖注入 is a :是一个,继承. has a:有一个,成员变量,依赖. class B { private A a; //B类依赖A类 } ...
- 利用蒙特卡洛(Monte Carlo)方法计算π值[ 转载]
部分转载自:https://blog.csdn.net/daniel960601/article/details/79121055 圆周率π是一个无理数,没有任何一个精确公式能够计算π值,π的计算只能 ...
- InstallShield 创建 visual studio 工程的时候 指向 任意 visual studio 版本 方法 (修改 计算机 默认 visual studio shell 版本)
这需要 修改 计算机 默认 visual studio shell 版本 注册表 HKEY_CLASSES_ROOT VisualStudio.DTE 配置节点 描述的是 默认的 visual stu ...
- 背水一战 Windows 10 (91) - 文件系统: Application Data 中的文件操作, Application Data 中的“设置”操作, 通过 uri 引用 Application Data 中的媒体
[源码下载] 背水一战 Windows 10 (91) - 文件系统: Application Data 中的文件操作, Application Data 中的“设置”操作, 通过 uri 引用 Ap ...
- 「PKUWC2018」随机游走(min-max容斥+FWT)
「PKUWC2018」随机游走(min-max容斥+FWT) 以后题目都换成这种「」形式啦,我觉得好看. 做过重返现世的应该看到就想到 \(min-max\) 容斥了吧. 没错,我是先学扩展形式再学特 ...