有借用,但原文出处已经找不到了,根据笔记分享一下解释器的基础。

下面的代码表示,等待两秒钟,输出‘test is running'。

现在要求增加统计程序运行时间的功能。

等待两秒钟,输出‘test is running',现要求增加统计程序运行时间的功能。

import time

def test():

time.sleep(2)

print('test is running!')

test()

学习先问为什么,有什么用,学基础的时候有时不理解为什么简单的事情要搞那么复杂,而对应的实际应用时,往往“这个复杂方法有很多优点和简化了很多事情”。学基础时用简单的例子,只是为了讲明知识点,而不要去关注例子实现的什么功能,这个功能当然是个‘屁’了。

那么,装饰器的实际应用场景:程序已上线或已使用,但需要增加新功能,修改原函数不合理也不科学(这里真的包含了很多背景声音),就要求:

(1)不能修改原功能函数的代码。例子中的功能是非常简单的,要实现当然是直接修改,但现实中一个功能的实现是非常复杂的代码,直接修改是不合理不科学的。

(2)不能修改原函数的调用方式。在符合第一条的情况下,调用时仍然是用test(),即老方法能实现新功能。现实中后面程序在反复用test(),就是要完全不动老代码的基础上,增加一个’装饰器‘更新整个程序。

(3)上述说的老方法是表面上的,这就是装饰器介入的作用。

好,以下开始改造,用试错的方法解释装饰器的实现过程和原理。

满足条件(1)可以增加代码如下:

def deco(func):

start=time.time()

func()

stop=time.time()

print(stop-start)

deco(test)

#把老代码里的test函数作为参数传递给新函数

#(因为是增加新功能,老功能还是要的,所以新代码里肯定要引用老代码的功能,就采取了这种方法)

看上去新功能就实现了,但可以看到调用方式变为了deco(test),即违背了条件(2),以前程序里可能反复调用了test(),都要改成deco(test),不科学。

同时满足条件(2),再改:

思路:产生一个新函数,重新赋值给test,test=某函数,那么后面反复调用的test()就被实质上改过来了,实现功能。

#试一下:

test=deco(test) #计算右边的,是一个两行字符串,赋值给test根本不是一个函数。

test() #因此跳错误码

再试一下:

增加:return func

然后:

test=deco(test)

test()

代码正常运行,但因为return func的缩进和其他代码是同级的,所以deco(test)这步已经把新功能给实现了,又返回了一次test(),结果重复。

把下面完整的代码去试一下,出现了两次test is running ,不合格。

import time

def test():

time.sleep(2)

print('test is running!')

def deco(func):

start=time.time()

func()

stop=time.time()

print(stop-start)

return func

test=deco(test)

test()

思路没有错,上述这里return一个函数的思考过程也是对的,只是返回的方式不对,应当使用’嵌套函数‘。

def timer(func):

def deco():

start=time.time()

func()

stop=time.time()

print(stop-start)

return deco

#把deco()嵌套在timer(func)里,返回一个deco()函数的函数名deco;

#调用timer(func)时,deco()里面的过程代码类似于没有执行的,

#被打包成了一个函数,执行的只是return了这个函数的函数名。

test=timer(test)

#右边代码返回的是一个deco()的函数名deco,deco()打包了作为被参数传入的原test()里的功能,

#同时增加了新功能。

test()

#符合(2)要求,没有改变调用方法,但实质上这句调用的已经是deco()了。

#顶格代码是不能调用经过了二次缩进的嵌套函数的,

#但这里用了deco()用了return,成了闭包函数,就可以被调用了。

至此,本质上是修改了调用函数,但在表面上并未修改调用方式,而且实现了附加功能,需求实现。

真正的装饰器:语法糖

在原test()的上一行加上@timer,删除test=timer(test).

而且要把新增的函数写在原函数的上面

最后代码

import time

def timer(func):

print(func.__name__) #看看打印出来的是什么

def deco():

start=time.time()

func()

stop=time.time()

print(stop-start)

return deco

@timer

def test():

time.sleep(2)

print('test is running')

#test=timer(test)这句不用了,注释掉

test()

过程比较啰嗦,但每一步都看下来后,装饰 器的原理就知道了,涉及到有参数的时候,再另外理解了。

python编写装饰器_我也来写一下python装饰器相关推荐

  1. python k线合成_手把手教你写一个Python版的K线合成函数

    手把手教你写一个Python版的K线合成函数 在编写.使用策略时,经常会使用一些不常用的K线周期数据.然而交易所.数据源又没有提供这些周期的数据.只能通过使用已有周期的数据进行合成.合成算法已经有一个 ...

  2. 怎么把python程序发给别人_想把你写的Python程序发给别人用?打包成exe啊!

    前言 大家好,欢迎来到编程教室! 当你学了一段时间Python,终于写出一个小游戏的时候,是不是很想发给你的小伙伴分享一下你的成果?但是,如果直接将xx.py文件发给别人,别人通常是不能直接运行的,他 ...

  3. 用python编写图片生成器_不到100行代码 Python制作一个九宫格图片生成器,炫酷朋友圈!...

    朋友圈下面的这种图片排列风格,相比大家一定会很熟悉,有关于职位招聘的 Snipaste_2020-08-02_19-48-58.png 祝贺节日的, Snipaste_2020-08-02_19-49 ...

  4. python老师 课时费_花10分钟写一个Python脚本,搞定了初中老师一下午的工作

    有个朋友是一个初中老师.嗯,教学行政两手抓的那种初中老师. 一天晚上突然微信问我,怎么把图片转成PDF.懵了一下,这个直接打印成PDF不就可以了? 遂告诉他,结果感觉两个人不是一个世界的: 好不容易教 ...

  5. 100行的python作品详解_漫画喵的100行Python代码逆袭

    小喵的唠叨话:这次的博客,讲的是使用python编写一个爬虫工具.为什么要写这个爬虫呢?原因是小喵在看完<极黑的布伦希尔特>这个动画之后,又想看看漫画,结果发现各大APP都没有资源,最终好 ...

  6. python response重头开始_你必须学写 Python 装饰器的五个理由

    你必须学写Python装饰器的五个理由 ----装饰器能对你所写的代码产生极大的正面作用 作者:Aaron Maxwell,2016年5月5日 Python装饰器是很容易使用的.任何一个会写Pytho ...

  7. python class用法理解_通过钢铁侠变身快速理解Python的装饰器用法

    1 一切都要从函数说起 我们都知道一个函数可以返回一些数据,然后这些数据可以被其他函数调用.函数里还可以有若干个参数,可以让函数根据不同的输入值进行不同的计算,然后得到新的结果. 于是,我们的故事就可 ...

  8. 用python编写密码安全性_用大数据python保护密码

    本篇文章给大家带来的就是关于用大数据Python保护密码,大数据时代,各种网站都需要你注册账号,使用密码.往往大家为了省事,所有的平台的账号密码是一样的,假如某个网站数据泄露后,那你的隐私安全就有问题 ...

  9. python编写脚本方法_【Python】教你一步步编写banner获取脚本

    Hello 各位小伙伴们大家好,周末过的愉快吗? 刚好最近学习了使用python编写banner获取脚本,今天就跟大家一起一步一步再学习一遍吧. Part.1 说明篇 什么是banner? banne ...

最新文章

  1. matlab批量对图片进行添加椒盐噪声并批量保存到文件夹
  2. (转载)VS2010/MFC编程入门之三十六(工具栏:工具栏资源及CToolBar类)
  3. sweetalert插件的使用
  4. c语言4钟存储类型关键字用法,求C语言中的32个关键字及其意思? C语言中32个关键字的意思和用法~!...
  5. nginx 日志格式设置 和 负载均衡下 获取真实ip
  6. linux实战清理挖矿病毒kthreaddi
  7. html 获取下一个兄弟节点,js jquery获取当前元素的兄弟级 上一个 下一个元素
  8. AbiWord 中Piece Table 数据结构的实现----AbiWord Documentation
  9. Mac解压Windows 压缩文件(.zip格式)乱码问题
  10. Thinking in Java 9.9 接口与工厂
  11. 中国智能手机行业的江湖事
  12. fiddler运行原理_fiddler工作原理
  13. linux查看dubbo版本号,Dubbo 疯狂更新!
  14. java对象转换为map
  15. 女朋友都看得懂的服务器搭建(纯小白超详细图文教程,阿里云服务器搭建)
  16. gamit添加未知天线
  17. 数据分析师与数据科学家的区别
  18. 后端理解ajax和axios
  19. 《隐私保护周三见》86问 | 交流群互动合集
  20. VGG多种网络结构的搭建以及感受野的计算

热门文章

  1. 专访雷果国:从1.5K到18K 一个程序员的5年成长之路
  2. 什么是真正的高清,你知道吗?
  3. H264 解码耗时分析
  4. 对Docker常用命令的整理
  5. jdbc写入和读取过程
  6. HTTP协议中request报文请求方法和状态响应码
  7. SUSE11 搭建iscsi target 配置
  8. 1023:坑爹的黑店
  9. BZOJ-1034 泡泡堂
  10. 安卓开发.四大组件.activity.1