1、python作用域
在介绍python装饰器前,先简单说下python作用域:
L>E>G>B(调用先后顺序)
L:local---->函数内部作用域
E:enclosing---->函数内部与内嵌函数之间
G:global----->全局作用域
B:build-in----->内置作用域
passline = 60 # global
def fun(val): # val----->enclosing
var passline = 90 # 这里的passline是local函数内部作用域
if val>passline:
print(pass)
else:
print(fail)
def inner_func():
print(val)
1)上面例子中,在函数外部定义了一个变量passline,这个是全局变量,作用域 global
2)在函数内部重新定义了passline,这个就是local函数内部变量,作用域local,还是内部
3)在最后,定义了一个函数,inner_func,里面打印了val,这个val不是内部作用于,全局作用域也没有定义,它是通过外层函数传递过来的参数,这个就是函数内部与内嵌函数之间的变量,即enclosing
2、python装饰器:
装饰器的作用:装饰器可以在不改变函数体和函数调用的情况下,在该函数执行前或者执行后进行其他操作。
1)python装饰器用来装饰函数的
2)将被装饰函数作为参数传递给装饰器
3)将装饰器函数的返回值,赋值给被装饰函数
4)语法糖:@deco
python装饰器本质其实就是对闭包的使用。
下面通过一个简单的例子来说明:
执行结果如下:
可以看到我们的装饰器执行过程是这样的:
1)执行装饰器函数deco,并将函数bar作为参数传递给deco,此时打印出"call deco..."
2)装饰器函数deco返回函数in_deco,赋值给被装饰函数bar,此时bar函数即为in_deco函数
3)我们调用bar()函数,即执行in_deco(),打印出"in deco...",并调用了func(),也就是我们最先传递进去的bar原始函数
4)在in_deco内部调用了我们前面传递进去的bar函数,此时打印出原来bar函数中的语句 "call bar..." 1 2
3、多个装饰器可以叠加使用,python解释器解释装饰器从下至上,执行从上而下。
如下例:
上图中,写了两个装饰器:登录验证和权限认证
对home() 函数使用了登录验证装饰器
对indes() 函数同时使用了登录验证和权限认证装饰器
python解释器会首先将两个装饰器加载到内存中。
下面以indes()函数为例,说明整个解释器执行过程,假设是以admin身份登录的。
解释器解释过程如下:
1)python解释器解释admin_check,并把indes作为参数fun传递给admin_check函数
2)admin_check函数返回的inner函数,暂命名admin_inner,将会作为login_required 装饰器的参数传递给login_required函数。
3)login_required 函数 返回的inner函数(暂命名login_inner)再次被被装饰函数接收
解释完后,开始从上往下执行:
1)解释器会去执行上面第3)返回的inner函数,即我们命名的login_inner,打印出login
2)然后执行login_inner中的fun,即上面第2)中login_required 接收的参数 admin_inner,此时会打印出admin
3)执行admin_inner中的fun函数,即上面1)中admin_check接收的参数,即indes函数,所以此时会打印出index
4、带参数装饰器
上面讲的两个例子都是不带参数的,装饰器也是可以单参数的,看下面一个例子:
如上如,定了两个函数before和after,在使用装饰器的时候,分别将两个函数作为参数传递进去,wrapper(before, after) 整个函数返回值即login_required将作为装饰器,其他同上面没有参数的装饰器