这是在Python学习小组上介绍的内容,现学现卖、多练习是好的学习方式。

第一步:最简单的函数,准备附加额外功能

# -*- coding:gbk -*-
'''示例1: 最简单的函数,表示调用了两次'''def myfunc():print("myfunc() called.")myfunc()
myfunc()

第二步:使用装饰函数在函数执行前和执行后分别附加额外功能

# -*- coding:gbk -*-
'''示例2: 替换函数(装饰)
装饰函数的参数是被装饰的函数对象,返回原函数对象
装饰的实质语句: myfunc = deco(myfunc)'''def deco(func):print("before myfunc() called.")func()print("  after myfunc() called.")return funcdef myfunc():print(" myfunc() called.")myfunc = deco(myfunc)myfunc()
myfunc()

第三步:使用语法糖@来装饰函数

# -*- coding:gbk -*-
'''示例3: 使用语法糖@来装饰函数,相当于“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()

第四步:使用内嵌包装函数来确保每次新函数都被调用

# -*- coding:gbk -*-
'''示例4: 使用内嵌包装函数来确保每次新函数都被调用,
内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''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()

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

# -*- 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 -*-
'''示例6: 对参数数量不确定的函数进行装饰,
参数用(*args, **kwargs),自动适应变参和命名参数'''def deco(func):def _deco(*args, **kwargs):print("before %s called." % func.__name__)ret = func(*args, **kwargs)print("  after %s called. result: %s" % (func.__name__, ret))return retreturn _deco@deco
def myfunc(a, b):print(" myfunc(%s,%s) called." % (a, b))return a+b@deco
def myfunc2(a, b, c):print(" myfunc2(%s,%s,%s) called." % (a, b, c))return a+b+cmyfunc(1, 2)
myfunc(3, 4)
myfunc2(1, 2, 3)
myfunc2(3, 4, 5)

第七步:让装饰器带参数

# -*- 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()

第八步:让装饰器带 类 参数

# -*- coding:gbk -*-
'''示例8: 装饰器带类参数'''class locker:def __init__(self):print("locker.__init__() should be not called.")@staticmethoddef acquire():print("locker.acquire() called.(这是静态方法)")@staticmethoddef release():print("  locker.release() called.(不需要对象实例)")def deco(cls):'''cls 必须实现acquire和release静态方法'''def _deco(func):def __deco():print("before %s called [%s]." % (func.__name__, cls))cls.acquire()try:return func()finally:cls.release()return __decoreturn _deco@deco(locker)
def myfunc():print(" myfunc() called.")myfunc()
myfunc()

第九步:装饰器带类参数,并分拆公共类到其他py文件中,同时演示了对一个函数应用多个装饰器

# -*- coding:gbk -*-
'''mylocker.py: 公共类 for 示例9.py'''class mylocker:def __init__(self):print("mylocker.__init__() called.")@staticmethoddef acquire():print("mylocker.acquire() called.")@staticmethoddef unlock():print("  mylocker.unlock() called.")class lockerex(mylocker):@staticmethoddef acquire():print("lockerex.acquire() called.")@staticmethoddef unlock():print("  lockerex.unlock() called.")def lockhelper(cls):'''cls 必须实现acquire和release静态方法'''def _deco(func):def __deco(*args, **kwargs):print("before %s called." % func.__name__)cls.acquire()try:return func(*args, **kwargs)finally:cls.unlock()return __decoreturn _deco
# -*- coding:gbk -*-
'''示例9: 装饰器带类参数,并分拆公共类到其他py文件中
同时演示了对一个函数应用多个装饰器'''from mylocker import *class example:@lockhelper(mylocker)def myfunc(self):print(" myfunc() called.")@lockhelper(mylocker)@lockhelper(lockerex)def myfunc2(self, a, b):print(" myfunc2() called.")return a + bif __name__=="__main__":a = example()a.myfunc()print(a.myfunc())print(a.myfunc2(1, 2))print(a.myfunc2(3, 4))

Python之装饰器入门相关推荐

  1. python 装饰器入门

    1. 装饰器入门 1.1. 需求是怎么来的? 装饰器的定义很是抽象,我们来看一个小例子. ? 1 2 3 4 def foo():     print 'in foo()'    foo() 这是一个 ...

  2. python中装饰器的作用_Python装饰器详解,详细介绍它的应用场景

    装饰器的应用场景附加功能 数据的清理或添加:函数参数类型验证 @require_ints 类似请求前拦截数据格式转换 将函数返回字典改为 JSON/YAML 类似响应后篡改为函数提供额外的数据 moc ...

  3. python装饰器函数-Python函数装饰器常见使用方法实例详解

    本文实例讲述了Python函数装饰器常见使用方法.分享给大家供大家参考,具体如下: 一.装饰器 首先,我们要了解到什么是开放封闭式原则? 软件一旦上线后,对修改源代码是封闭的,对功能的扩张是开放的,所 ...

  4. python nonetype_python装饰器 ——@符号与“TypeError: ‘NoneType’ object is not callable” | 学步园...

    今天来讨论一下装饰器.装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数 ...

  5. 专题10:如何应对面试官的拷问—你了解python的装饰器吗?

    python之详解装饰器 应用场景 简单的装饰器 本质上的装饰器 嵌套函数 闭包 面试中的装饰器 通用的装饰器 带参的高级装饰器 多个装饰器 面试官:你了解装饰器吗? XXX:了解 面试官:那你说说吧 ...

  6. Python之装饰器

    Python之装饰器 在不修改函数调用方式的前提下,也不能修改函数内部源代码!!!! 例如: 在每个季度公司发绩效,统计每个人的代码执行效率.咱们总不能是每个函数里加time模块吧. import t ...

  7. Python设计模式-装饰器模式

    Python设计模式-装饰器模式 代码基于3.5.2,代码如下; #coding:utf-8 #装饰器模式class Beverage():name = ""price = 0.0 ...

  8. 浅谈Django的中间件与Python的装饰器

    浅谈Django的中间件 与Python的装饰器 一.原理 1.装饰器是Python的一种语法应用,利用闭包的原理去更改一个函数的功能,即让一个函数执行之前先到另外一个函数中执行其他需求语句,在执行该 ...

  9. Python的装饰器

    详解Python的装饰器 本文源码 https://github.com/tobyqin/python_decorator Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都 ...

最新文章

  1. linux 快捷matlab_Linux命令 笔记(一)
  2. python自动化上传图片_接口自动化之Python3_Requests之上传头像
  3. 数据仓库系列1-高质量数据建模
  4. python——动态的增加实例方法、类方法、静态方法
  5. SQL Server 数据库部分常用语句小结
  6. 最小生成树Prime算法
  7. 创建vue项目(二)引入elementUi、axios、准备静态资源、封装组件(.vue,js代码等)
  8. CentOS6.8升级gcc到4.8.5总结
  9. HttpContext.Current.Cache在控制台下不工作
  10. 多小区下小区上行速率的计算(5)
  11. IR2103H桥驱动电路
  12. linux系统服务器如何登陆,linux系统如何登录到远程linux服务器
  13. 【Matlab】三维绘图总结
  14. 云MAS - MT-提交状态码
  15. 弥散张量成像(diffusion tensor imaging,DTI)常用指标
  16. 微信小程序链接后台接口,进行数据交互
  17. c语言兑换100人民币,100 元人民币有几多种换零方式
  18. ArrayList 和 Vector 的区别
  19. 流利阅读12.27 Why life expectancy in America is down again
  20. java英里转换成千米_英里和公里怎么换算

热门文章

  1. JAVA写出来的塔防能有多好玩?......真香!
  2. SQLite 作者最新开源力作
  3. 皮一皮:谁来解释下一无所有的字典含义?
  4. Nacos 1.3.0 发布,一个修炼内功的版本:全新内核构建!
  5. 面试:说说你对 Java 中 final 的理解?
  6. 一文搞懂 ThreadLocal 原理
  7. Spring Cloud Stream消费失败后的处理策略(一):自动重试
  8. 利用SPRING管理热加载的GROOVY对象!
  9. 计算机课代表自荐信,课代表自荐信范文
  10. python 模板匹配多个物体