12. 闭包

一、闭包

  在一个函数内部,我们可以在在定义一个函数,并且将内部的函数作为外部函数的返回值返回。这种高阶函数,我们也称为 闭包。“闭” 是指该函数是内嵌函数,“包” 是指该函数包含外层函数作用域的引用(不是对全局作用域)。通过闭包,我们可以创建一些只有当前函数能访问的变量,我们可以将一些私有的数据藏在闭包中。

  形成闭包的要件:① 函数嵌套;② 将内部函数作为返回值返回;③内部函数必须要使用外部函数的变量

  正常来说,调用一个函数的时候,这个函数中的所有局部变量+形参都只会在这个函数执行过程中才会保留,只要这个函数执行完毕,那么这些局部变量+形参就会被自动释放,也就说没有了。闭包比普通的函数强大的地方在于,它在外部函数执行完毕之后,这个外部函数中的所有局部变量+形参,都不会被释放,以便在于调用内部函数的时候可以使用。

  闭包的好处可以将局部变量永久存储,但是多占用内存;由于闭包会携带包含它的函数的作用域,因此会比其它函数占用更多的内存。因此,可以手动解除会匿名函数的引用,以便释放内存;

def outer(count=0):
    # 在函数内部再定义一个函数
    def inner():
        print("我是内部函数")
        # 内层函数修改外层函数的数据
        nonlocal count  
        count += 1
        # 内层函数访问外层函数的数据
        print(count)
    return inner

fun = outer()
fun()
fun()
fun()

  fun 是一个函数,它是调用 outer() 后返回的函数。这个函数是在 outer() 内部定义的,并不是全局函数,所以这个函数总是能访问到 fun() 函数内的变量。在闭包中的内部函数中,如果没有用 nonlocal 关键字来声明外部函数的变量,则不能对其进行修改,只能进行访问;

二、闭包的应用

  通过闭包我们可以在没有改变原函数的前提下,拓展功能。

def add(a,b):
    return a+b

def say_hello():
    print("hello world!")

def outer(func):
    """
    用来对其它函数进行扩展,使其函数可以在执行前打印开始执行,执行后打印执行结束
    @param inner 要扩展的函数
    @return inner 返回扩展函数
    """

    # 创建一个新函数
    def inner(*args, **kw_args):
        # 在原函数执行前扩展功能
        print("开始执行!")

        # 调用被扩展的函数
        result = func(*args, **kw_args)

        # 在原函数执行后拓展功能
        print("执行结束!")

        # 返回函数执行结果
        return result
  
    # 返回新函数
    return inner

# 将原函数名指向的内存地址偷梁换柱成装饰器内部新创建函数(inner())的内存地址
add = outer(add)
result = add(10,20)
print(result,'\n')

say_hello = outer(say_hello)
say_hello()
posted @ 2024-09-28 18:31  星光映梦  阅读(14)  评论(0编辑  收藏  举报