Python 装饰器常用的创建方式及源码示例解析

Python 装饰器常用的创建方式及源码示例解析

目录

装饰器简介

基础通用装饰器

源码示例

执行结果

带参数装饰器

源码示例

源码结果

源码解析

多装饰器执行顺序

源码示例

执行结果

解析

类装饰器

源码示例

执行结果

解析

装饰器简介

装饰器(decorator)是一种高级Python语法。可以对一个函数、方法或者类进行加工。在Python中,我们有多种方法对函数和类进行加工,相对于其它方式,装饰器语法简单,代码可读性高。因此,装饰器在Python项目中有广泛的应用。修饰器经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理, Web权限校验, Cache等。

装饰器的优点是能够抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。即,可以将函数“修饰”为完全不同的行为,可以有效的将业务逻辑正交分解。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。例如记录日志,需要对某些函数进行记录。笨的办法,每个函数加入代码,如果代码变了,就悲催了。装饰器的办法,定义一个专门日志记录的装饰器,对需要的函数进行装饰。

基础通用装饰器 源码示例 def wrapper_out(func): print('-- wrapper_out start --') def inner(*args, **kwargs): print("-- inner start --") ret = func(*args, **kwargs) print("-- inner end --") return ret print('-- wrapper_out end --') return inner @wrapper_out def test(): print("--test--") return 1 * 2 if __name__ == '__main__': print(">>>>>>>>>>>>>>") print(test()) 执行结果

-- wrapper_out start --
-- wrapper_out end --
>>>>>>>>>>>>>>
-- inner start --
--test--
-- inner end --
2

带参数装饰器 源码示例 def wrapper_out(mode=None): print('-- wrapper_out start --') def inner_1(func): print("-- inner_1 start --") def inner_2(*args, **kwargs): print("-- inner_2 start --") print(f"mode: {mode}") ret = func(*args, **kwargs) print("-- inner_2 end --") return ret print("-- inner_2 end --") return inner_2 print('-- wrapper_out end --') return inner_1 @wrapper_out(mode=2) def test(): print("--test--") return 1 * 2 if __name__ == '__main__': print(">>>>>>>>>>>>>>") print(test()) 源码结果

-- wrapper_out start --
-- wrapper_out end --
-- inner_1 start --
-- inner_2 end --
>>>>>>>>>>>>>>
-- inner_2 start --
mode: 2
--test--
-- inner_2 end --
2

源码解析

带参数的装饰器函数, 需要多嵌套一层, 外层装饰器的参数

预加载的时候已经是根据函数的编写顺序进行加载

执行顺序在对应的最内存函数中调用最外层的装饰器函数参数

被装饰函数是最为 inner_1 的参数进行传入, 被装饰函数的参数是作为 inner_2 的参数传入

被装饰函数的执行位置是在 inner_2 中, 使用inner_1 的参数变量和 inner_2 的参数变量共同协助下进行执行

同时还要使用装饰器函数 wrapper_out 的参数变量进行额外的操作

多装饰器执行顺序 源码示例 def wrapper_out1(func): print('-- wrapper_out_1 start --') def inner1(*args, **kwargs): print("-- inner_1 start --") ret = func(*args, **kwargs) print("-- inner_1 end --") return ret print('-- wrapper_out1 end --') return inner1 def wrapper_out2(func): print('-- wrapper_out_2 start --') def inner2(*args, **kwargs): print("-- inner_2 start --") print("-- inner_2 end --") print('-- wrapper_out_2 end --') return inner2 @wrapper_out2 @wrapper_out1 def test(): print("--test--") return 1 * 2 if __name__ == '__main__': print(">>>>>>>>>>>>>>") print(test()) 执行结果

-- wrapper_out_1 start --
-- wrapper_out1 end --
-- wrapper_out_2 start --
-- wrapper_out_2 end --
>>>>>>>>>>>>>>
-- inner_2 start --
-- inner_1 start --
--test--
-- inner_1 end --
-- inner_2 end --
2

解析

装饰器的预加载顺序是从上往下, 先将装饰器函数写入内存

装饰器的执行顺序是以最靠近函数体的装饰器开始执行(从内到外)

类装饰器 源码示例 class WrapperOut(object): def __init__(self, func): print('start init ~~~~~`') print('func name is %s ' % func.__name__) self.__func = func print('end init ~~~~~`') def __call__(self, *args, **kwargs): print('start test') self.__func() print('end test') @WrapperOut def test(): print('this is test func') if __name__ == '__main__': print(">>>>>>>>>>>") test() 执行结果

start init ~~~~~`
func name is test 
end init ~~~~~`
>>>>>>>>>>>
start test
this is test func
end test

解析

类装饰器是利用了类初始化 init 析构方法来处理 被装饰函数的传入

以及使用 call 方法来满足被装饰函数的执行触发

到此这篇关于Python 装饰器常用的创建方式及解析的文章就介绍到这了,更多相关python装饰器创建方式内容请搜索易知道(ezd.cc)以前的文章或继续浏览下面的相关文章希望大家以后多多支持易知道(ezd.cc)!

推荐阅读

    excel怎么用乘法函数

    excel怎么用乘法函数,乘法,函数,哪个,excel乘法函数怎么用?1、首先用鼠标选中要计算的单元格。2、然后选中单元格后点击左上方工具栏的fx公

    excel中乘法函数是什么?

    excel中乘法函数是什么?,乘法,函数,什么,打开表格,在C1单元格中输入“=A1*B1”乘法公式。以此类推到多个单元。1、A1*B1=C1的Excel乘法公式

    标准差excel用什么函数?

    标准差excel用什么函数?,函数,标准,什么,在数据单元格的下方输入l标准差公式函数公式“=STDEVPA(C2:C6)”。按下回车,求出标准公差值。详细

    excel常用函数都有哪些?

    excel常用函数都有哪些?,函数,哪些,常用,1、SUM函数:SUM函数的作用是求和。函数公式为=sum()例如:统计一个单元格区域:=sum(A1:A10)  统计多个

    cpu所有电脑都通用吗|电脑CPU通用吗

    cpu所有电脑都通用吗|电脑CPU通用吗,,1. 电脑CPU通用吗CPU和主板并不是都通用。CPU与主板搭配的最基本要求就是接口要对应。现在Intel产品