装饰器函数
装饰器:在函数运行时增加功能且不影响这个函数原有内容
普通装饰器函数
语法:
1 |
|
@符号为装饰器函数语法,也常叫做语法糖
先来看一个简单的装饰器函数实现:
1 | def wai(func):#装饰器函数,参数部分接收一个函数对象 |
执行后的结果:
1 | this is nei |
此时的foo函数在原有的基础上,额外多了装饰器函数中的定义的功能
被装饰函数foo在调用时,其实本质上是在进行 wai(foo)()
wai(foo)()
过程解析:
- 装饰器函数wai接收被装饰函数foo作为参数
- 返回return nei,闭包函数nei被返回
- nei()函数调用
- 由于nei函数的返回值为return func(),所以在内函数调用结束时,被装饰函数也会被调用
被装饰函数在调用时,被调用的函数有三个:
wai() nei()
以及
被装饰函数
func()
接下来,让我们充满动力的继续看这样一个例子
被装饰的函数带有参数
我们考虑到,之前的普通装饰器并不能解决;被装饰函数带有参数的问题,如果有这样一个函数
1 | def foo(a,b): |
这个函数在定义时,明确两个参数,并且做相加打印的操作
我们有一个胆大的想法,在这个两值相加函数运行后的结果,分别给 a和 b两值多100,但是不修改这个原有 foo函数
1 | def wai(func):#装饰器函数 |
按照惯有思维,3+5的结果应该是8,但是由于该函数被装饰,我们来看下结果吧:
1 | 30 |
执行后的结果,并不是本身的3+5
装饰器函数内部的闭包函数参数部分接收到了被装饰函数传入的参数,并且在其内部进行了值的修改
最后在闭包函数的返回值处,将修改后的函数传入到return func(a,b),此时被装饰函数调用,但是传入的参数已经不再是之前的3和5了
装饰器函数带有参数
最后,让我们看一下装饰器函数的终极套路
如果我们装饰器函数需要参数怎么办?
你会发现,此时wai函数和nei函数的参数部分都有了自己的意义,那么这个装饰器函数的参数该怎么接收?
1 | def arg_func(choice='Man'): #我们额外包装一层函数用来接收装饰器函数的参数 |
执行的效果
1 | 请输入你的性别:Man |
总结
实现装饰器
- 定义闭包函数
- 闭包函数返回装饰器函数接收参数调用
- 装饰器函数参数部分接收被装饰函数对象
- 闭包函数参数部分接收被装饰函数参数部分
- 如果需要装饰器函数带参数,在最外层在包裹一层函数,形参部分接收装饰器函数参数,返回装饰器函数即可
Author: kangyuetao
Link: https://kangyuetao.github.io/38966/
Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.
