python中的闭包

2021-02-18 21:18

阅读:489

标签:语法糖   ret   pytho   python   闭包函数   完成   形式   常用   name   

一、闭包的理解

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中的闭包

标签:语法糖   ret   pytho   python   闭包函数   完成   形式   常用   name   

原文地址:https://www.cnblogs.com/jaysonteng/p/12688627.html


评论


亲,登录后才可以留言!