python装饰器学习总结(理解其原理)

最近在网上找到一个python装饰器的学习视频,感觉由浅入深讲的很好理解,所以博主在这里把那个老师讲解的步骤,重点记录一下

一。对装饰器最基本的理解:

比如现在有一百个函数,我们想给这100个函数加一个新功能,我们肯定不能直接把原程序停了,然后一点一点修改源代码。那么这时候就要用到装饰器了。

或者说装饰器的作用就是 不修改源代码以及原函数调用方式的情况下 给原函数增加新的功能
python装饰器学习总结(理解其原理)
原则总结成一句话:装饰器对被装饰的函数来说是透明的。

下面会讲到,装饰器本质是高阶函数+嵌套函数

二。实现装饰器知识储备

python装饰器学习总结(理解其原理)
1.函数就是“变量“的理解
只要在函数执行前,定义过函数,执行就不会有错

下图是变量,函数在python存储的概图。
python装饰器学习总结(理解其原理)
(大矩形表示python整个存储空间。)

比如下面这段代码,虽然 函数bar()是在 foo()之后定义的,但是只要是在 foo()执行之前 定义过了,就可以执行成功(内存中可以找到bar()对应的存储空间)
python装饰器学习总结(理解其原理)
再来一个例子加深理解,下面我定义了一个test函数。我直接输入test,显示的一串十六进制数是内存地址。test相当于一个”门牌号“,单独输数test是查看这个门牌号是多少,输入test()才是访问门牌号对应的内容。
python装饰器学习总结(理解其原理)
我让fun = test,然后我直接fun()也可以运行(类似 上图中x=1 y=x 那么x,y都指向1)。到这里,大家基本可以理解函数即变量的含义了吧。
python装饰器学习总结(理解其原理)

2.高阶函数:
高阶函数两个特点:
1.把一个函数名当作实参传给另外一个函数
(作用:可以实现 在不修改被装饰函数源代码的情况下为其添加功能
如下图
python装饰器学习总结(理解其原理)
bar()函数 源代码没有改变,只是改变了调用方式:由 bar()→test1(bar) 给bar()增加了查看程序运行时间的功能。

2.返回值中包含函数名。
(作用:可以实现 不修改函数的调用方式

python装饰器学习总结(理解其原理)

3.嵌套函数
理解下面基本的嵌套函数样例
python装饰器学习总结(理解其原理)
注意bar()是不能在外面调用的,因为它是一个内部函数,上面说了半天 函数即变量,所以把它看成一个内部变量,它只存在于foo()函数运行的过程中。

注意:下面这样的不算 嵌套函数,这是属于函数的调用。嵌套函数必须得是用“def” 在函数中创建了函数。
python装饰器学习总结(理解其原理)

三。高阶函数+嵌套函数 =》 装饰器

示例一:
python装饰器学习总结(理解其原理)
上面这段代码 timer()函数就是我们定义了一个装饰器,我们可以发现,它结合了嵌套函数与高阶函数。

python装饰器学习总结(理解其原理)
上面定义了两个函数(被装饰器装饰的函数)
python装饰器学习总结(理解其原理)
根据上面的知识,我们可以知道,用装饰器给test1()函数增加功能时,需要这样(上图)调用。这样就能保证装饰器的规则:不改变函数源代码;不改变函数调用方式。
其实我们说不改变函数调用方式,但其实调用的时候,调用的已经不是原函数了,test1已经换成了deco()

但是每次都这样给一个“与test1同名”的变量赋值就很麻烦,所以采用下图方法:
再需要被装饰(增加功能)的函数前加上**@装饰器名** ,这个语句就相当于 test1=timer(test1)
python装饰器学习总结(理解其原理)

因为可能被装饰的函数 需要传的参数数量不一定,比如 def test() 传0个参数; def test(name,age) 需要传2个参数,我们怎么使装饰器满足这样的可变需求的,看下面划线部分代码。加两个非固定参数,这样就能解决了。
python装饰器学习总结(理解其原理)