在python中,装饰器的作用就是在不改变函数本身的前提下,可以对函数增加装饰,先举个例子
def outer(func): #装饰函数 def inner(): print("before") func() print("after") return inner def f1(): #被装饰的函数 print("fffff") f1 = outer(f1) f1()
执行过程:
发现outer函数,不执行内部结构,扔内存
发现f1函数,不执行内部结构,扔内存
执行outer函数 参数是 f1函数名
进入outer函数,发现inner函数,不执行内部结构,扔内存
执行return 返回inner函数的函数名
从outer函数出来,将 inner函数名 赋给 f1函数的函数名
调用f1函数 这里实际上就是执行了inner函数(上一步)
进入inner函数内部,输出before
调用func() func参数是传递进来的f1函数名,所以实际上调用的是 f1()
进入f1函数体,输出fffff
退出f1()函数,继续执行输出 after
结束
从这个例子可以看出,在没有改变f1函数的内部结构的同时, 在我们调用f1时使它还能输出before after
相当于装饰了f1函数
而我们上述代码可以改写为
def outer(func): def inner(): print("before") func() print("after") return inner @outer def f1(): print("fffff") f1()
等效于第一个代码
@outer 完成了
f1 = outer(f1)
便于书写 实际中都是 @+装饰函数 (不是被装饰函数!!!) 放在被装饰函数的上一行
我们执行f1函数, 就是执行装饰函数里的 inner函数
补充
1.这里有人可能就有疑问,这么麻烦,我直接写到f1函数中不就行了
我这里的解释是 开发封闭原则
简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即:
- 封闭:已实现的功能代码块
- 开放:对扩展开发 具体细节本文不做讨论(因为我也是表面了解, 不要在意细节~)
2. 函数如果没有返回值,默认返回None
上述代码 在装饰器函数outer中 如果return inner()
会执行inner() 然后inner函数没有返回值 返回None
return None
所以这里不能加() 仅仅是函数名的赋值
执行func()时 执行这里f1()是原f1() 因为是你首先将f1传递给形参之后 f1函数名才被改变的 然后调用的func()
返回去再看一遍就明白了~
第二弹~
def outer(func): def inner(): print("before") i = func() print("after") return i return inner @outer def f1(): print("fffff") return "OK" f1()
和第二份源码不同的是,这个被装饰函数有返回值,我们装饰器的目的是在不改变函数本身的前提下,可以对函数进行装饰
而我们的被装饰函数返回 ok 所以我们要变成加粗的样子
当然我们不能写成
def inner(): print("before") return func() print("after") return innerprint("after")就不会被执行了