python中闭包及其应用场景

1.介绍

闭包,如果内函数使用了外函数的局部变量,并且外函数把内函数返回出来的过程,叫做闭包,里面的内函数是闭包函数
目的:为函数创建一段内存区域(内部变量自己使用),并为其维护数据,以后执行方便使用。(应用场景:装饰器,SQLAchermy源码)
特征 内函数使用了外函数的局部变量,那么该变量与闭包函数发生绑定,延长该变量的生命周期;
**闭包的意义:**闭包可以优先使用外函数中的变量,并对闭包中的值起到了封装保护的作用.外部无法访问.
示例:

def outfunc(x):
    def infunc(y):
        return x+y
    return infunc
if __name__ == "__main__":
    a = outfunc(2)
    b = a(3)
    print("a:", a)
    print("b:", b)

执行结果:
闭包示例
在函数infunc中对外部变量x进行了引用,并且外部函数outfunc的返回结果是内部函数infunc,所以变量a得到的实际上是一个对于函数infunc的引用,当执行a时,即是在执行内部函数infunc.
注意:当内部函数对引用的外部函数的局部变量进行改动时:
1.一般来说当一个函数执行结束时会将其临时变量释放将内存返回,但闭包比较特殊,当其结束时返回内部函数的时候会将其临时变量进行绑定一起返回给内部函数;
2.当内部函数要对外部函数的临时变量进行修改时不能进行直接修改,有两种方法:(1)使用关键字nolocal进行声明向上一层寻找该变量(2)可变数据类型比如列表可以进行修改。(可变数据类型修改时不会修改其地址,添加内容可以改变成功,不可变数据类型对其修改时会改变其内存地址)
所以应该说是闭包无法改变外部函数局部变量指向的内存地址。

def outer(a):
    b = [1, 2, 3, 4]

    def inner():
        nonlocal a
        a += 12
        b[0] += 1
        return a, b
    return inner

inner = outer(34)
print(inner())    #  (46, [3, 2, 3, 4])
#  即使多次调用inner()其外部临时变量会在基础上继续改变,而不是说一次执行完就将临时变量a或b释放掉
print(inner())    #  (58, [3, 2, 3, 4])

2.闭包的应用场景

闭包用来保留当前的状态实现基于现在状态的更新。

import random


def outer(situation):
    def inner():
        situation[0] += 1
        situation[1] += random.randint(0, 4)
        return situation
    return inner


inner = outer([15, 155])
for i in range(16, 25):
    person = inner()
    age = person[0]
    high = person[1]
    print('小明{}岁时的身高是{}cm'.format(age, high))

执行结果:

小明16岁时的身高是155cm
小明17岁时的身高是155cm
小明18岁时的身高是155cm
小明19岁时的身高是159cm
小明20岁时的身高是163cm
小明21岁时的身高是166cm
小明22岁时的身高是170cm
小明23岁时的身高是173cm
小明24岁时的身高是173cm

闭包在装饰器以及单例上上的应用,详见其他篇章

你可能感兴趣的:(漫漫python路,python,开发语言,后端)