闭包装饰器
Posted kmnskd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了闭包装饰器相关的知识,希望对你有一定的参考价值。
python的装饰器首先要了解闭包是什么?
-
通常情况下我们定义一个普通函数是这样做的:
def func(): print (‘哈哈哈‘)
-
普通函数的返回值默认为None,也可以自己决定return
-
-
闭包函数:
-
定义:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。
-
把函数作为返回值返回回来。
def wai(n): def nei(): sum_num = 0 for i in range(n): sum_num = sum_num + i return sum_num return nei res = wai(4) print(res) print(res()) ? <function wai.<locals>.nei at 0x0000016C95E0F6A8> 6
-
上面的例子可以看出来wai()函数的返回值是一个求和函数,对res进行调用得到6。
-
在这个例子中,我们在函数lwai中又定义了函数nei,并且,内部函数nei可以引用外部函数wai的参数和局部变量,当wai返回函数nei时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。
-
当我们不需要立即得到结果时,可以用闭包的方式保留这个值。
a = wai(4) b = wai(4) print(id(a)) print(id(b)) ? 3126981621416 3126981621552
-
上面的示例可得a和b两个对象是相互独立的,在内存中有不同的id,所以数据也是独立的。
-
装饰器
-
装饰器是不修改原函数代码,也不修改其他调用该函数的代码的前提下为函数添加新功能。
-
我的理解:普通闭包是把一般数据类型的变量当做参数传入,而装饰器则是把一个函数当做变量传入,并且在其内部调用该函数之前为其添加新的功能。
-
看代码:
def wai(func): def nei(): print(‘这是函数传入之前的操作‘) func() print(‘这是函数传入之后的操作‘) return nei ? def func(): print(‘我是被装饰的函数‘) ? res = wai(func) res() ? 这是函数传入之前的操作 我是被装饰的函数 这是函数传入之后的操作
-
例子分析:我们可以看到装饰器的流程是把函数func当做变量传入wai()函数,函数往下走就是调用nei()函数,nei()函数中紧接着又调用func();再看下面调用首先是wai(func),而wai(func)的返回值就是我们闭包里所讲是个函数,即nei函数,所以要看到print结果就要对这个返回值再次调用,把返回值保存成res,对其调用。
-
从这段代码得出:
-
1.函数的参数传递的其实是引用,而不是值。
-
2.函数名也可以是一个变量,所以可以重新赋值。
-
3.赋值操作的时候,先执行等号右边的。
-
-
-
上面的例子看完我们再看看正经写代码时的规范。也就是用@符号代替了res = wai(func)和res()这两个步骤,方便写代码。我们只需要调用被装饰函数即可。
def wai(func): def nei(): print(‘这是函数传入之前的操作‘) func() print(‘这是函数传入之后的操作‘) return nei @wai def func(): print(‘我是被装饰的函数‘) func() ? 这是函数传入之前的操作 我是被装饰的函数 这是函数传入之后的操作
装饰器的分类
-
普通装饰器:即不带任何参数,就是上面的例子。
-
被装饰函数带参数:
def wai(func): def nei(a): print(‘传入函数之前的操作‘) func(a) print(‘传入函数之后的操作‘) return nei @wai def func(a): print(‘我是被装饰函数的参数:‘,a) func(2) ? 传入函数之前的操作 我是被装饰函数的参数: 2 传入函数之后的操作
-
装饰器带有参数:
def head(b): def wai(func): def nei(a): print(‘我是装饰器的参数:‘,b) print(‘传入函数之前的操作‘) func(a) print(‘传入函数之后的操作‘) return nei return wai @head(5) def func(a): print(‘我是被装饰函数的参数:‘,a) func(2) ? 我是装饰器的参数: 5 传入函数之前的操作 我是被装饰函数的参数: 2 传入函数之后的操作
-
两个装饰器
def w1(func): print(‘---正在装饰--‘) def inner(): print(‘---正在验证权限1--‘) func() return inner ? ? def w2(func): print(‘---正在装饰2--‘) def inner(): print(‘---正在验证权限2--‘) func() return inner ? # 只要python解释器执行到了这个代码,那么就会自动的进行装饰,而不是等到调用的时候才装饰的 @w2 @w1 def f1(): print(‘---f1‘) ? f1() ? 输出结果: ---正在装饰-- ---正在装饰2-- ---正在验证权限2-- ---正在验证权限1-- ---f1
以上是关于闭包装饰器的主要内容,如果未能解决你的问题,请参考以下文章