野路子码农(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中函数可以调用 ...
随机推荐
- Windows10访问Ubuntu子系统(WSL)的桌面环境
原文地址:https://blog.csdn.net/xmh19936688/article/details/90212960 Windows10访问Ubuntu子系统(WSL)的桌面环境文章目录Wi ...
- 在window上安装mysql - MySQL5.7.24 版本
1.下载安装包 下载地址:https://dev.mysql.com/downloads/mysql/5.7.html#downloads 点击Download,选择 No thanks, just ...
- clr via c# 接口
1,常用接口及其定义 public interface IDisposable{ void Dispose(); } public interface IEnumerable}{ IEnumerato ...
- C#设计模式学习笔记:(6)适配器模式
本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7640873.html,记录一下学习过程以备后续查用. 一.引言 从今天开始我们开始讲结构型设计模式,结构型设 ...
- kong服务网关API
kong服务网关API pingforever关注 0.1762017.05.23 11:16:08字数 834阅读 7,367 kong简介 Kong 是在客户端和(微)服务间转发API通信的API ...
- 简单的试了试async和await处理异步的方式
今天无意中就来试了试,感觉这个新的方法还是非常行的通的,接下来我们上代码 这段代码想都不用想输出顺序肯定是//null null 233,当然出现这个问题还是因为它是同步,接下来我们就进行异步方式来处 ...
- 监控redis cluster 主从实例是否切换,切换前后对应关系
需求:编写脚本实现对redis cluster 主从是否发生主从切换进行监控,若发生切换,输出切换前后主从对应关系. 初始化对比文件,仅执行一次,后续不需要在执行,除非该文件不存在. cmd=&quo ...
- 常用 Jenkins 配置
General Use custom workspace Directory: {directory, d:\github\} Source Code Management Git plugin Gi ...
- Centos 7 安装配置git
Centos 7 安装配置git 1.安装git yum install git 2.验证git git -version 3.配置基本信息
- HQL查询 HQL Named parameter [xxx] not set 的解决办法
org.springframework.dao.InvalidDataAccessResourceUsageException: Named parameter [xxx] not set; nest ...