python中的闭包
Posted 学习笔记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python中的闭包相关的知识,希望对你有一定的参考价值。
一、闭包的理解
1、相当于函数中,嵌套另一个函数并返回此嵌套的函数。代码如下:
def func(name): # 定义外层函数 def inner_func(age): # 内层函数 print(‘name: ‘, name, ‘, age: ‘, age) return inner_func # 注意此处要返回,才能体现闭包 bb = func(‘jayson‘) # 将字符串传给func函数,并赋值给变量 bb(28) # 通过变量,调用func函数,返回inner_func,并将年龄传入inner_func,从而完成闭包
2、可以将函数理解为一个变量
import time def timer(func): start = time.time() time.sleep(1) end = time.time() print(‘the time is %s‘ % ( end- start)) return func # 返回函数本身 def test(a): print(‘this is test: %s‘ % (a)) test = timer(test) # 将test函数当成变量传入timer函数 test(‘aa‘) # 通过变量test,调用timer返回的func函数,传入参数,执行
>> the time is 1.000964641571045
二、最常用于装饰器
1、装饰器基本原理:
将函数A当成变量传入装饰函数D,执行了装饰操作后,变量传回给了函数A。类似于 test = test -1(你编写了test函数,经过装饰后,你调用test,执行的是test-1)
import time def timer(func): start = time.time() time.sleep(1) end = time.time() print(‘the time is %s‘ % ( end- start)) return func # 返回函数本身 @timer # 装饰器(语法糖):相当于test = timer(test),对timer传入了test封装了一下,传回给了test def test(a): print(‘this is test: %s‘ % (a)) test(‘aa‘) # 此处执行与上一代码(一、2)中输出结果一样
>> the time is 1.000964641571045
2、如果函数传入参数不确定,就使用*arg,**kwarg
import time # 定义装饰器 def timer(func): def wrapper(*arg, **kwrgs): # 这样,后面会根据外部参数形式自动切换,比较灵活 start = time.time() func(*arg, **kwrgs) # 注意此处也需要使用此类型参数 end = time.time() print(‘the time is %s‘ % ( end- start)) return wrapper # 一定要返回函数进行闭包 @timer # 装饰器 def test(a): time.sleep(2) print(‘this is test: %s‘ % (a)) test(‘a‘) # 调用函数 # 输出: >> this is test: a >> the time is 2.000917673110962
3、带参数的装饰器(装饰器加括号,带参数)
import time # 定义装饰器 def timer(deco_para): # 装饰器添加参数 if deco_para == ‘a‘: def out_wrapper(func): # 此时,func往下移了一层 def wrapper(*arg, **kwrgs): start = time.time() res = func(*arg, **kwrgs) # 若函数有func函数有返回值,此处需将返回值储存 end = time.time() print(‘the time is %s‘ % ( end- start)) return res # 将func函数的返回值返回(如果func无返回值,此处不需要返回) return wrapper # 返回闭包函数 print(‘wrapper_a is used‘) # 注意此行代码在定义func函数时候即执行,无需调用函数,所以这也是如果想要通过调用函数再执行装饰操作,需要再定义个wrraper嵌套函数的原因。 return out_wrapper # 返回包裹函数 elif deco_para == ‘b‘: # 根据装饰器的参数,选择闭包 def out_wrapper(func): #同上 def wrapper(*arg, **kwrgs): start = time.time() res = func(*arg, **kwrgs) end = time.time() print(‘the time is %s‘ % ( end- start)) return res return wrapper # 同上 print(‘wrapper_b is used‘) return out_wrapper # 同上 @timer(deco_para=‘a‘) # 调用装饰函数 def test1(a): time.sleep(2) print(‘this is test: %s‘ % (a)) return 666 @timer(deco_para=‘b‘) def test2(a): time.sleep(2) print(‘this is test: %s‘ % (a)) return 888 test1(‘test1‘) print(‘*‘ * 50) test2(‘test2‘) # 输出 >> wrapper_a is used # 在定义test1时候就执行此代码 wrapper_b is used # 在定义test2时候就执行此代码 this is test: test1 # 后面的是在调用函数之后执行 the time is 2.0003035068511963 ************************************************** # 此行除外 this is test: test2 the time is 2.000523090362549 out[5]: 888
以上是关于python中的闭包的主要内容,如果未能解决你的问题,请参考以下文章