python装饰器–原来如此简单

今天整理装饰器,内嵌的装饰器、让装饰器带参数等多种形式,非常复杂,让人头疼不已。但是突然间发现了装饰器的奥秘,原来如此简单。。。。

# -*- coding:gbk -*-
'''示例1: 使用语法糖@来装饰函数,相当于“myfunc = deco(myfunc)”
但发现新函数只在第一次被调用,且原函数多调用了一次'''def deco(func):print("before myfunc() called.")func()print("  after myfunc() called.")return func@deco
def myfunc():print(" myfunc() called.")myfunc()
myfunc()

这是一个最简单的装饰器的例子,但是这里有一个问题,就是当我们两次调用myfunc()的时候,发现装饰器函数只被调用了一次。为什么会这样呢?要解释这个就要给出破解装饰器的关键钥匙了。
这里@deco这一句,和myfunc = deco(myfunc)其实是完全等价的,只不过是换了一种写法而已
一定要记住上面这句!!!!
好了,从现在开始,只需要做替换操作就可以了。
将@deco 替换为 myfunc = deco(myfunc)
程序首先调用deco(myfunc),得到的返回结果赋值给了myfunc (注意:在Python中函数名只是个指向函数首地址的函数指针而已)
而deco(myfunc)的返回值就是函数myfunc()的地址
这样其实myfunc 没有变化,也就是说,最后的两次myfunc()函数调用,其实都没有执行到deco()。
有同学就问了,明明打印了deco()函数里面的内容啊,怎么说没有调用到呢。这位同学一看就是没有注意听讲,那一次打印是在@deco 这一句被执行的。大家亲自动手试一下就会发现” myfunc() called.” 这句打印输出了三次。多的那次就是@deco这里输出的,因为@deco 等价于myfunc = deco(myfunc),这里已经调用了deco()函数了。

第二步 :确保装饰器被调用

怎么解决装饰器没有被调用的问题呢

# -*- coding:gbk -*-
'''示例2: 使用内嵌包装函数来确保每次新函数都被调用,
内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''def deco(func):def _deco():print("before myfunc() called.")func()print("  after myfunc() called.")# 不需要返回func,实际上应返回原函数的返回值return _deco@deco
def myfunc():print(" myfunc() called.")return 'ok'myfunc()
myfunc()

这里其实不需要我解释了,还是按照第一步中的方法做替换就可以了。还是啰嗦几句吧。。
@deco 替换为 myfunc = deco(myfunc)
程序首先调用deco(myfunc),得到的返回结果赋值给了myfunc ,这样myfunc 就变成了指向函数_deco()的指针
以后的myfunc(),其实是调用_deco()

第三步 :对带参数的函数进行装饰

破案过程和第一步、第二步完全一致,不再重复了

# -*- coding:gbk -*-
'''示例5: 对带参数的函数进行装饰,
内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''def deco(func):def _deco(a, b):print("before myfunc() called.")ret = func(a, b)print("  after myfunc() called. result: %s" % ret)return retreturn _deco@deco
def myfunc(a, b):print(" myfunc(%s,%s) called." % (a, b))return a + bmyfunc(1, 2)
myfunc(3, 4)

第四步 :让装饰器带参数

# -*- coding:gbk -*-
'''示例7: 在示例4的基础上,让装饰器带参数,
和上一示例相比在外层多了一层包装。
装饰函数名实际上应更有意义些'''def deco(arg):def _deco(func):def __deco():print("before %s called [%s]." % (func.__name__, arg))func()print("  after %s called [%s]." % (func.__name__, arg))return __decoreturn _deco@deco("mymodule")
def myfunc():print(" myfunc() called.")@deco("module2")
def myfunc2():print(" myfunc2() called.")myfunc()
myfunc2()

这种带参数的装饰器怎么解释呢。其实是一样的,还是我们的替换操作
@deco(“mymodule”)替换为myfunc = deco(“mymodule”)(myfunc )
注意啊,这里deco后面跟了两个括号。
有同学要问了,这是什么意思?
其实很简单,先执行deco(“mymodule”),返回结果为_deco
再执行_deco(myfunc),得到的返回结果为__deco
所以myfunc = __deco

破案!

本文是转载文章,原文章地址:https://blog.csdn.net/u013858731/article/details/54971762

python装饰器–原来如此简单相关推荐

  1. python装饰器原理-简单了解python装饰器原理及使用方法

    这篇文章主要介绍了简单了解python装饰器原理及使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 如果你接触 Python 有一段时间了的话 ...

  2. python简单装饰器_python装饰器的简单示例

    这篇文章主要为大家详细介绍了python装饰器的简单示例,具有一定的参考价值,可以用来参考一下. 对python这个高级语言感兴趣的小伙伴,下面一起跟随512笔记的小编两巴掌来看看吧! 装饰器的语法以 ...

  3. Python装饰器——四两拨千斤还是杀鸡用牛刀?

    一.引言 最近做了一个小小小项目,写了一些偏工程的代码.项目的目的看起来很简单,就是去组里的一个能显示调试信息网站上,根据我们提供的一堆查询,获取调试信息的response,然后离线的解析来完成后续实 ...

  4. python装饰器实例-Python装饰器原理与简单用法实例分析

    本文实例讲述了Python装饰器原理与简单用法.分享给大家供大家参考,具体如下: 今天整理装饰器,内嵌的装饰器.让装饰器带参数等多种形式,非常复杂,让人头疼不已.但是突然间发现了装饰器的奥秘,原来如此 ...

  5. 简单介绍python装饰器

    这篇文章简单介绍一下python装饰器,希望对你们有所帮助. 简单正常python例子: def up(text):return text.upper() #转成大写 def lo(text):ret ...

  6. python装饰器实例-Python装饰器简单用法实例小结

    本文总结分析了Python装饰器简单用法.分享给大家供大家参考,具体如下: 装饰器在python中扮演着很重要的作用,例如插入日志等,装饰器可以为添加额外的功能同时又不影响业务函数的功能. 比如,运行 ...

  7. Python中的装饰器的简单介绍02

    这篇博文转载自伯乐在线的12步轻松搞定python装饰器,重构成python3. 1. 函数 在python中,函数通过def关键字.函数名和可选的参数列表定义.通过return关键字返回值.我们举例 ...

  8. python装饰器使用教学,Python教程|简单上手Python中装饰器的使用

    如何打造极简主义风格网站教程 .极简主义与其他设计风格<极简主义设计之美> 这篇文章的一部分是讲极简主义是如何与其他设计风格很好配合的.可以把极简主义当作一种属性,而它可以添加或结合其他. ...

  9. python简单装饰器_简单介绍Python装饰器(一)

    装饰器的作用 相信大家在 探索过程中已经了解装饰器的作用,也有很多花里胡哨的介绍. 这次小冰也来讲解一下关于Python装饰器的一些小知识. 它的作用: 性能测试 日志 安全验证 ...... 相信大 ...

最新文章

  1. 线段树扫描线求矩形周长详解
  2. 能打羽毛球又能击穿墙壁,戴上这款机械臂,秒变蜘蛛侠反派「章鱼博士」
  3. a 中调用js的几种方法整理及使用推荐
  4. 【小练习06】HTML+CSS--教学大讲堂
  5. oracle 强制恢复,oracle数据库恢复
  6. 机器学习(2.sklearn(Scikit-learn)库、字典数据的特征抽取)
  7. VTK:PolyData之ColorCellsWithRGB
  8. 安装MySQL之后,在cmd中MySQL命令不能识别
  9. C++ 对引用的理解4
  10. github基本使用教程
  11. 直播回顾:如何对付臭名昭著的 IO 夯?诊断利器来了 | 龙蜥技术
  12. 某8086cpu构成的微型计算机,微型计算机原理及应用试题及答案
  13. 小组互评Alpha版本
  14. android 模板设计,Android的设计模式-模板方法模式
  15. 干货!10分钟,用Python生成图文并茂的PDF报告!
  16. 软件用户手册编写指南(GB8567一88/GB8567一2006)
  17. vue 解决跨域问题(开发环境)
  18. Scrapy添加headers
  19. HDU 4238 You Are the One
  20. Pixelmator Pro 1.7 Mac版下载

热门文章

  1. 利用百度语音识别技术实现文字转语音的应用(Java版附源码)
  2. CNAME(cname)
  3. 2016年兰州交通大学校园选拔赛
  4. 计算机散热程序,电脑的散热方法
  5. 推荐七款靠谱的Download工具 多平台
  6. lucky前面加a还是an_luck、lucky、luckily的区别和用法-luckly-英语-徐似眉同学
  7. The type okio.ByteString cannot be resolved. It is indirectly referenced from required .class files
  8. js 解决页面切换时,定时器setInterval会变得很慢,有时候不执行的问题
  9. 外国客户一般汇款到国内需要多久时间?
  10. Python实现素描画