hi,大家新年好,已经有很长一段时间没有分享自己的python方面的技术,这次分享下自己总结的python装饰器方面,主要有以下几点:
装饰器定义与作用
函数装饰器
类装饰器
装饰器的嵌套
带参数的装饰器
装饰器是如何管理函数和类
装饰器定义与作用
定义
在定义的函数或者类的方法或者类使用的修饰符修饰,后面可以是一个函数或者是一个类
作用
可以理解为对原函数对象或者类对象进行代理或者包装,增强原有的函数和类功能
能够管理函数对象和函数调用,也能够管理定义类对象的类本身和实例对象
函数装饰器
函数装饰器:函数实际被调用的时候会直接返回一个由函数装饰器包装好的函数对象进行回调,可以修饰在函数或定义的类方法
编写基本的函数装饰器
类装饰器
类装饰器:类实际被调用的时候会直接返回一个由函数装饰器包装好的类进行回调,让该类具有某种属性或行为
注意上述使用装饰器修饰的Person已经是调用装饰器函数并返回Person对象,即定义类的时候已经拥有装饰器的功能,因此不论如何调用Person()创建实例,上面仅会打印一次intercept
Person()分两步:
其一,执行包装的intercept然后返回原Person类,也就是获取到的Person已经调用过装饰器里面的方法
其二,利用装饰器返回的Person类再创建对象
嵌套的装饰器
函数装饰器嵌套
类装饰器嵌套
的装饰器
修饰带有参数的函数的装饰器,这时候装饰器的作用就是返回一个函数的代理
上述的被装饰器修饰的fn等价于proxy,在函数proxy中已经保存了fn函数的对象因此调用fn()就等价于调用proxy(),而proxy()函数增加了auth认证校验,即:
再进一步拆分,即:
修饰带有参数初始化类的装饰器
定义一个装饰器函数并传递类对象
在定义的装饰器函数内部定义一个代理函数对象,此代理函数对象与原函数传递的参数一致,并负责处理装饰器拦截方法等工作,最后返回一个类对象
此时使用装饰器修饰类必须重载运算符保证可被动态调用(类似与反射创建类对象)
注意体会与上述定义类装饰器的区别,这个时候定义的Person并非Person类,而是一个定义在decorator函数内部的一个代理函数,这个代理函数保存了aClass这个类对象,即:
,
进一步拆分,即:
定义的装饰器函数传递参数
利用装饰器有效地管理函数和类
使用装饰器要分清楚以下几点:
使用装饰器修饰的函数或者类主要应用场景是什么,是直接返回原函数(类)还是嵌套定义的代理函数对象
如果是直接返回园函数或者是类,那么可以保证修饰前后的数据属性是一致的,并且能够获取原数据的属性信息
如果返回的是一个包装原函数或者类的代理函数对象,那么此时数据属性便发生改变,这种情况下一般多适用于调用的方式
领取专属 10元无门槛券
私享最新 技术干货