野路子码农(5)Python中的装饰器,可能是最通俗的解说
装饰器这个名词一听就充满了高级感,而且很多情况下确实也不常用。但装饰器有装饰器的好处,至少了解这个对装逼还是颇有益处的。网上有很多关于装饰器的解说,但通常都太过“循序渐进”,有的还会讲一些“闭包”之类的概念,像我这种脑子不太好使的经常就是前读后忘……所以我想自己来写一个非常通俗易懂的解说。
个人最早真正接触装饰器是在Kaggle上看别人使用numba加速,函数前一行短短的 @jit 让你的代码快到飞起,看起来也很简洁。那究竟装饰器是什么,它又能干嘛呢?
P1 装饰器的作用
装饰器的作用是对多种函数执行一个通用操作。重点是多种和通用。举个栗子来说,我写了一个计算执行时长的装饰器,那么我可以把它安在函数A上,也可以把它安在函数B上,甚至安在任何函数上,因为装饰器执行的是一个通用操作,与我把它安在哪个函数上基本无关。注意,这里我们说“多种函数”而不是“任意函数”,因为有些装饰器有特殊用途,并不能在任意函数身上通用。
P2 装饰器的本体
我们来看一下装饰器的结构:
def 装饰器(函数模板):
骚操作 + 函数模板 (称为wrapper)
return wrapper
所以装饰器的本质还是一个函数,这也就是为什么我们说装饰器的作用是执行一个操作,只不过和那些普通平凡的函数都不同的是,装饰器的操作是通用的。
那么问题又来了,这个”wrapper“又是什么鬼?wrapper说白了就是一系列骚操作和函数模板的集合,装饰器函数返回的就是wrapper,也就是说它返回了函数的return和你所定义的骚操作。
至于函数模板,它不是任何一个特定的函数,它只是一个泛指。我们可以来看一下wrapper的结构,这里我写的是个最通用的函数模板(通过*args和**kwargs传递任意参数):
def wrapper(*args, **kwargs):
前置操作
func = function(*args, **kwargs)(即函数模板)
后置操作
return func
func = function(*args, **kwargs) 使我们得到了函数执行的结果,无论这个函数是什么函数,而return func将结果返回,连同前后的操作一起作为wrapper扔出去。
P3 一个例子
好了,接下来我们来写个例子,一个计算执行时长的装饰器:
import time def simple_timeit(function):
def wrapper(*args, **kwargs):
start = time.time() # 记录开始时间
func = function(*args, **kwargs)
print("用时%.4fs"%(time.time() - start)) # 输出(结束时间-开始时间)
return func
return wrapper
现在我们随便写两个函数,并给它们装上装饰器:
@simple_timeit
def sleep(): # 无参数函数
time.sleep(3)
return "Get up!!!"
@simple_timeit
def break_str(string): # 有参数函数
txt = [t.upper() for t in string.split(" ")]
return txt
执行一下看看结果:


可以看到对于不同的函数类型,我们的计时器都是通用的。
总的来说,装饰器能让我们的代码变得简洁,而且能在多个函数上通用。再者由于它是在函数之上额外附加的操作,所以我们只要将装饰器那一行注释掉就能关闭附加功能,而又不影响函数本体的功能,可以说非常方便啦,所以有机会还是值得一用的~
野路子码农(5)Python中的装饰器,可能是最通俗的解说的更多相关文章
- 野路子码农系列(2)Python中的类,可能是最通俗的解说
啥叫佩奇?啥叫类?啥叫面向对象?后面两个问题以前在大学里“祖传谭浩强”的时候我经常会有所疑问.老师说着一堆什么public, private,我都是一脸懵逼,啥叫私有?为啥要私有?然后就神游天外了…… ...
- 野路子码农系列(1) 创建Web API
新工作正式开始了2天,由于客户暂时还没交接数据过来,暂时无事可做.恰逢政佬给某超市做的商品图像识别的项目客户催收了,老板要求赶紧搞个API,于是我就想我来试试吧. 说起API,我其实是一窍不通的,我对 ...
- 简单说明Python中的装饰器的用法
简单说明Python中的装饰器的用法 这篇文章主要简单说明了Python中的装饰器的用法,装饰器在Python的进阶学习中非常重要,示例代码基于Python2.x,需要的朋友可以参考下 装饰器对与 ...
- 【Python】python中的装饰器——@
对装饰器本来就一知半解的,今天终于弄清楚了,Python中的装饰器是对装饰者模式的很好运用,简化到骨子里了. python中为什么需要装饰器,看这里:http://www.cnblogs.com/hu ...
- Python 中实现装饰器时使用 @functools.wraps 的理由
Python 中使用装饰器对在运行期对函数进行一些外部功能的扩展.但是在使用过程中,由于装饰器的加入导致解释器认为函数本身发生了改变,在某些情况下——比如测试时——会导致一些问题.Python 通过 ...
- 写python中的装饰器
python中的装饰器主要用于在已有函数实现功能前附加需要输出的信息,下面将用实例展示我如何写装饰器. 首先分别尝试写装饰器装饰一个无参函数和一个有参函数(被装饰函数仅输出,无返回值情况下) def ...
- python中的装饰器decorator
python中的装饰器 装饰器是为了解决以下描述的问题而产生的方法 我们在已有的函数代码的基础上,想要动态的为这个函数增加功能而又不改变原函数的代码 例如有三个函数: def f1(x): retur ...
- python中@property装饰器的使用
目录 python中@property装饰器的使用 1.引出问题 2.初步改善 3.使用@property 4.解析@property 5.总结 python中@property装饰器的使用 1.引出 ...
- 【Python】解析Python中的装饰器
python中的函数也是对象,函数可以被当作变量传递. 装饰器在python中功能非常强大,装饰器允许对原有函数行为进行扩展,而不用硬编码的方式,它提供了一种面向切面的访问方式. 装饰器 一个普通的装 ...
- 三分钟搞定Python中的装饰器
python的装饰器是python的特色高级功能之一,言简意赅得说,其作用是在不改变其原有函数和类的定义的基础上,给他们增添新的功能. 装饰器存在的意义是什么呢?我们知道,在python中函数可以调用 ...
随机推荐
- Java Web Servlet知识点讲解(二)
一.定义Servlet: public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpSer ...
- 错误:EfficientDet网络出现"No boxes to NMS"并且mAP:0.0的解决方案
近日,在使用谷歌新推出来的一个网络EfficientDet进行目标检测训练自己的数据集的时候,出现了如下错误: 其中项目开源地址是:https://github.com/toandaominh1997 ...
- 到2029年MRAM收入将增长170倍
一份新市场报告预计,从2018年到2029年,独立MRAM和STT-MRAM的收入将增长170倍,达到近40亿美元的收入.下一代内存技术的增长将主要由取代效率较低的内存技术(例如NOR闪存和SRAM) ...
- Linux /etc/network/interfaces
Linux下/etc/network/interfaces文件用来配置网络接口. 1. 使用动态IP地址 auto eth0 iface eth0 inet dhcp 2. 使用静态IP地址 auto ...
- gdck01
有好几年 好几年 好几年 我成天在抱怨 我没钱 我没钱 恨老天不开眼 不开眼 不开眼 为什么好的事 都跟我没有缘
- 12 : API
Object 概念 所有类的顶级父类 存在于java.lang包中,这个包不需要我们手动导包 常用方法 toString() 默认返回 类名@地址 的格式,来展示对象的地址值,如:a00000. ...
- C# WPF 表单更改提示
微信公众号:Dotnet9,网站:Dotnet9,问题或建议,请网站留言: 如果您觉得Dotnet9对您有帮助,欢迎赞赏 C# WPF 表单更改提示 内容目录 实现效果 业务场景 编码实现 本文参考 ...
- Java8新特性一览表
总览 forEach() method in Iterable interface(Iterable接口中的forEach()方法) default and static methods in Int ...
- 常见sql注入的类型
这里只讲解sql注入漏洞的基本类型,代码分析将放在另外一篇帖子讲解 目录 最基础的注入-union注入攻击 Boolean注入攻击-布尔盲注 报错注入攻击 时间注入攻击-时间盲注 堆叠查询注入攻击 二 ...
- QS Network ZOJ - 1586 板子题
#include<iostream> #include<algorithm> using namespace std; ; struct edge{ int a,b; doub ...