Python 装饰器(笔记,非原创)
定义:本质是函数,为其他函数添加附加功能
原则:1、不能修改被装饰的函数的源代码
         2、不能修改被装饰的函数的调用方式
知识储备:
       1、函数即“变量”
       2、高阶函数
      a:把一个函数名当作实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)
      b:返回值中包含函数名(不修改函数的调用方式)
       3、嵌套函数
         高阶函数+嵌套函数=》装饰器
第一步:最简单的函数,准备附加额外功能
| 1 2 3 4 5 6 7 8 | # -*- coding:gbk -*-'''示例1: 最简单的函数,表示调用了两次'''defmyfunc():    print("myfunc() called.")myfunc()myfunc() | 
第二步:使用装饰函数在函数执行前和执行后分别附加额外功能
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # -*- coding:gbk -*-'''示例2: 替换函数(装饰)装饰函数的参数是被装饰的函数对象,返回原函数对象装饰的实质语句: myfunc = deco(myfunc)'''defdeco(func):    print("before myfunc() called.")    func()    print("  after myfunc() called.")    returnfuncdefmyfunc():    print(" myfunc() called.")myfunc =deco(myfunc)myfunc()myfunc() | 
第三步:使用语法糖@来装饰函数
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # -*- coding:gbk -*-'''示例3: 使用语法糖@来装饰函数,相当于“myfunc = deco(myfunc)”但发现新函数只在第一次被调用,且原函数多调用了一次'''defdeco(func):    print("before myfunc() called.")    func()    print("  after myfunc() called.")    returnfunc@decodefmyfunc():    print(" myfunc() called.")myfunc()myfunc() | 
第四步:使用内嵌包装函数来确保每次新函数都被调用
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # -*- coding:gbk -*-'''示例4: 使用内嵌包装函数来确保每次新函数都被调用,内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''defdeco(func):    def_deco():        print("before myfunc() called.")        func()        print("  after myfunc() called.")        # 不需要返回func,实际上应返回原函数的返回值    return_deco@decodefmyfunc():    print(" myfunc() called.")    return'ok'myfunc()myfunc() | 
第五步:对带参数的函数进行装饰
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # -*- coding:gbk -*-'''示例5: 对带参数的函数进行装饰,内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''defdeco(func):    def_deco(a, b):        print("before myfunc() called.")        ret =func(a, b)        print("  after myfunc() called. result: %s"%ret)        returnret    return_deco@decodefmyfunc(a, b):    print(" myfunc(%s,%s) called."%(a, b))    returna +bmyfunc(1, 2)myfunc(3, 4) | 
第六步:对参数数量不确定的函数进行装饰
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # -*- coding:gbk -*-'''示例6: 对参数数量不确定的函数进行装饰,参数用(*args, **kwargs),自动适应变参和命名参数'''defdeco(func):    def_deco(*args, **kwargs):        print("before %s called."%func.__name__)        ret =func(*args, **kwargs)        print("  after %s called. result: %s"%(func.__name__, ret))        returnret    return_deco@decodefmyfunc(a, b):    print(" myfunc(%s,%s) called."%(a, b))    returna+b@decodefmyfunc2(a, b, c):    print(" myfunc2(%s,%s,%s) called."%(a, b, c))    returna+b+cmyfunc(1, 2)myfunc(3, 4)myfunc2(1, 2, 3)myfunc2(3, 4, 5) | 
第七步:让装饰器带参数
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # -*- coding:gbk -*-'''示例7: 在示例4的基础上,让装饰器带参数,和上一示例相比在外层多了一层包装。装饰函数名实际上应更有意义些'''defdeco(arg):    def_deco(func):        def__deco():            print("before %s called [%s]."%(func.__name__, arg))            func()            print("  after %s called [%s]."%(func.__name__, arg))        return__deco    return_deco@deco("mymodule")defmyfunc():    print(" myfunc() called.")@deco("module2")defmyfunc2():    print(" myfunc2() called.")myfunc()myfunc2() | 
第八步:让装饰器带 类 参数
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | # -*- coding:gbk -*-'''示例8: 装饰器带类参数'''classlocker:    def__init__(self):        print("locker.__init__() should be not called.")            @staticmethod    defacquire():        print("locker.acquire() called.(这是静态方法)")            @staticmethod    defrelease():        print("  locker.release() called.(不需要对象实例)")defdeco(cls):    '''cls 必须实现acquire和release静态方法'''    def_deco(func):        def__deco():            print("before %s called [%s]."%(func.__name__, cls))            cls.acquire()            try:                returnfunc()            finally:                cls.release()        return__deco    return_deco@deco(locker)defmyfunc():    print(" myfunc() called.")myfunc()myfunc() | 
第九步:装饰器带类参数,并分拆公共类到其他py文件中,同时演示了对一个函数应用多个装饰器
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | # -*- coding:gbk -*-'''mylocker.py: 公共类 for 示例9.py'''classmylocker:    def__init__(self):        print("mylocker.__init__() called.")            @staticmethod    defacquire():        print("mylocker.acquire() called.")            @staticmethod    defunlock():        print("  mylocker.unlock() called.")classlockerex(mylocker):    @staticmethod    defacquire():        print("lockerex.acquire() called.")            @staticmethod    defunlock():        print("  lockerex.unlock() called.")deflockhelper(cls):    '''cls 必须实现acquire和release静态方法'''    def_deco(func):        def__deco(*args, **kwargs):            print("before %s called."%func.__name__)            cls.acquire()            try:                returnfunc(*args, **kwargs)            finally:                cls.unlock()        return__deco    return_deco | 
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # -*- coding:gbk -*-'''示例9: 装饰器带类参数,并分拆公共类到其他py文件中同时演示了对一个函数应用多个装饰器'''frommylocker import*classexample:    @lockhelper(mylocker)    defmyfunc(self):        print(" myfunc() called.")    @lockhelper(mylocker)    @lockhelper(lockerex)    defmyfunc2(self, a, b):        print(" myfunc2() called.")        returna +bif__name__=="__main__":    a =example()    a.myfunc()    print(a.myfunc())    print(a.myfunc2(1, 2))    print(a.myfunc2(3, 4)) | 
Python 装饰器(笔记,非原创)的更多相关文章
- Python装饰器笔记
		DRY(Don't Repeat Yourself)原则: 一般是指在写代码的时候尽量避免重复的实现.违反DRY原则导致的坏处很容易理解,例如维护困难,修改时一旦遗漏就会产生不易察觉的问题. 一.函数 ... 
- Python 装饰器笔记
		一.装饰器无参数 1.原函数无参数 def wrap_in_tag_b(fn): # wrap_in_tag_b 是真正的装饰器 def wrapped(): return "<b&g ... 
- Python装饰器详解
		python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ... 
- 自创最精简的python装饰器
		个人心血原创,欢迎转载,请注明作者和出处.否则依法追究法律责任!!!! author:headsen chen date:2018-03-21 10:37:52 代码: 代码解析过程:1,def ... 
- Python 装饰器(Decorator)
		装饰器的语法为 @dec_name ,置于函数定义之前.如: import atexit @atexit.register def goodbye(): print('Goodbye!') print ... 
- 转发对python装饰器的理解
		[Python] 对 Python 装饰器的理解的一些心得分享出来给大家参考 原文 http://blog.csdn.net/sxw3718401/article/details/3951958 ... 
- [转]python 装饰器
		以前你有没有这样一段经历:很久之前你写过一个函数,现在你突然有了个想法就是你想看看,以前那个函数在你数据集上的运行时间是多少,这时候你可以修改之前代码为它加上计时的功能,但是这样的话是不是还要大体读读 ... 
- Python高级特性: 12步轻松搞定Python装饰器
		12步轻松搞定Python装饰器 通过 Python 装饰器实现DRY(不重复代码)原则: http://python.jobbole.com/84151/ 基本上一开始很难搞定python的装 ... 
- Python 装饰器学习心得
		最近打算重新开始记录自己的学习过程,于是就捡起被自己废弃了一年多的博客.这篇学习笔记主要是记录近来看的有关Python装饰器的东西. 0. 什么是装饰器? 本质上来说,装饰器其实就是一个特殊功能的函数 ... 
随机推荐
- python3笔记<一>基础语法
			随着AI人工智能的兴起,网络安全的普及,不论是网络安全工程师还是AI人工智能工程师,都选择了Python.(所以本菜也来开始上手Python) Python作为当下流行的脚本语言,其能力不言而喻,跨平 ... 
- 对象转Json时,Date类型格式化问题
			object是一个对象,该对象中有一个字段为Date类型 使用JSONObject obj = JSONObject.fromObject(object);将Object转成json时 Date类型字 ... 
- leetcode75
			class Solution { public: void sortColors(vector<int>& nums) { sort(nums.begin(), nums.end( ... 
- git  提交小备注
			总结: · git add -A 提交所有变化 · git add -u 提交被修改(modified)和被删除(deleted)文件,不包括新文件(new) · git add . 提交 ... 
- K8s部署使用CFSSL创建证书
			证书的编码格式 PEM(Privacy Enhanced Mail),通常用于数字证书认证机构(Certificate Authorities,CA),扩展名为.pem, .crt, .cer, 和 ... 
- Mybatis Generator 生成的mapper只有insert方法
			一般有两种情况 第一种是配置问题可以参考博客 http://blog.csdn.net/angel_xiaa/article/details/52474022 第二种是mysql-connector- ... 
- PostgreSQL使用笔记
			下载并安装 注意安装图形界面 pgAdmin 需要输入缺省用户 postgres 的密码 在 Windows 下安装之后注意把 bin文件夹加到 Path 环境变量中. 重置密码 使用管理员权限打开 ... 
- MySQL慢查询日志相关的配置和使用。
			MySQL慢查询日志提供了超过指定时间阈值的查询信息,为性能优化提供了主要的参考依据,是一个非常实用的功能,MySQL慢查询日志的开启和配置非常简单,可以指定记录的文件(或者表),超过的时间阈值等就可 ... 
- 2017-11-04 Sa Oct 消参
			2017-11-04 Sa $ P(-3, 0) $ 在圆C $ (x-3)^2 + y^2 = 8^2 $ 内,动圆M与圆相切且过P点,求M点轨迹. 设切点 $ A(a, b) $,圆心 \(M(x ... 
- SVN中英文菜单对照
			TortoiseSVN英文版菜单中文翻译01.SVN Checkout(SVN取出) 点击SVN Checkout,弹出检出提示框,在URL of repository输入框中输入服务器仓库地址,在C ... 
