Python进阶(33)—闭包

◎知识点

  1. 闭包的概述及使用


◎脚本练习

"""闭包"""

"""
    如果在一个函数的内部嵌套定义了另外一个函数(姑且将外部的函数和内部的函数分别称之为外函数和
内函数),内函数中引用了外函数中的变量,并且外函数的返回值是内函数,这样,就构成了一个闭包。
"""

def outer():
    a = 10
    def inner():
        print(a)
    return inner

"""
    通常情况下,在函数调用结束后,函数内定义的变量将不再可用。
    但是,对于闭包而言,在外函数调用结束后,外函数中被内函数引用的变量仍然是可以用,
因为外函数中被内函数引用的变量会被绑定到内函数的特殊属性__closure__中。
"""

def do_sth():
    temp = 8
    print(temp)

do_sth()
# print(temp)

outer_result = outer()
outer_result()  # 10
outer()()       # 10

print(outer_result.__closure__) # (<cell at 0x106153fa0: int object at 0x105f45a50>,)
print(outer_result.__closure__[0].cell_contents)    # 10

"""
    在默认情况下,在内函数中不能修改外函数中的变量引用的对象(如果引用的对象是可变类型的,
可以修改对象的内容)
"""

def outer2():
    a = 10
    def inner2():
        # 重新定义了一个变量a,把外函数中的变量a给屏蔽了
        # a = 11

        # 相当于a = a + 1
        # 重新定义了一个变量a,把外函数中的变量a给屏蔽了
        # 当计算等号右边的a + 1时,新定义的变量a还没有被赋值,因此程序报警
        # a += 1

        pass
    return inner2

def outer3():
    a = [3]
    def inner3():
        # 重新定义了一个变量a,把外函数中的变量a给屏蔽了
        # a = [1]

        # 变量a引用的对象是可变类型的,可以修改对象的内容
        a[0] = 8

        print(a)
    return inner3

outer3()()  # [8]

"""
    如果想在内函数中修改外函数中的变量所引用的对象,可以在内函数中使用关键字nonlocal对变量
进行声明,从而表明在内函数中并没有重新定义一个新的同名变量,而是使用外函数中该名称的变量。
"""

def outer4():
    a  = 10
    def inner4():
        nonlocal a

        # a = 11
        a += 1

        print(a)
    return inner4

outer4_result = outer4()
outer4_result()     # 11

"""
    对于内函数中引用的外函数中的变量,在调用内函数后对该变量的修改,在下一次调用内函数时仍然是
有效的,因为该变量会被绑定到内函数的特殊属性__closure__中。
"""

outer4_result()     # 12


◎脚本地址:https://github.com/anzhihe/learning/blob/master/python/practise/learn-python/python_advanced/closure.py

anzhihe 安志合个人博客,版权所有 丨 如未注明,均为原创 丨 转载请注明转自:https://chegva.com/5500.html | ☆★★每天进步一点点,加油!★★☆ | 

您可能还感兴趣的文章!

发表评论

电子邮件地址不会被公开。 必填项已用*标注