• Python闭包


    闭包函数的介绍

    闭包函数:内部函数包含对外部作用域非全局作用域名字的引用,并且一般外部函数的返回值为内部函数,这个内部函数叫做闭包函数。

    闭:内部函数

    包:内部函数引用了外部函数作用域的名称

    闭包函数示例:

    def outter():
        x = 111
        def inner():
            print(x)
        return inner
    
    res = outter() #res 就是内部函数 inner

    下面这个就不是闭包函数:

    x = 1
    def outter():
        def inner():
            print(x)
    
        return inner
    
    说明:因为x是全局作用域的变量,内部函数inner,包含的是全局作用域x的引用,根据闭包函数的定义,只有包含局部作用域名称的引用才是闭包函数。所以inner不是闭包函数。 

    函数.__closure__的返回值是一个cell对象组成的元组对象的话,那么这个函数是闭包函数。

    如果返回值为None,则不是闭包函数。

    def outter():
        x = 1
        y = 2
        def inner():
            print(x)
            print(y)
        print('inner', inner.__closure__)
        return inner
    
    res = outter()
    print(res.__closure__[0].cell_contents)
    print(res.__closure__[1].cell_contents)
    
    >>>inner (<cell at 0x1047f9ac8: int object at 0x1045abc00>, <cell at 0x1047f9af8: int object at 0x1045abc20>)
    >>>1  (x的值)
    >>>2  (y的值)
    
    说明:__closure__ 返回的长度等于局部作用域的名称的引用数量。可以看到元组中有两个cell,因为在闭包函数inner中,包含了两个局部作用域名称的引用。

    Python循环中不包含域的概念:

    func_list = []
    
    for i in range(3):
    
        def fun(x):
            return x*i
    
        func_list.append(fun)
    
    for func in func_list:
        print(func(3))
    
    >>>6
    >>>6
    >>>6

    当函数参数传入3时,如果想让结果为 0, 3 ,6 时,这时候就要用到闭包

    func_list = []
    
    for i in range(3):
        def outter(i):
            def fun(x):
                return x*i
            return fun
    
        func_list.append(outter(i))
    
    for func in func_list:
        print(func(3))
    
    >>>0
    >>>3
    >>>6
    
    说明:局部名称空间中,查找名称的顺序在函数定义时就已经确定。

    下面这种闭包会报错:

    def outter():
        a = 1
        def inner():
            a = a + 1
            return a
        return inner
    
    res = outter()
    res()
    
    
    >>>    a = a + 1
    UnboundLocalError: local variable 'a' referenced before assignment
    
    说明:在闭包函数inner中,Python将等于号左边的符号视为一个变量,所以inner函数中等于号左边的a是inner函数的局部名称空间的变量。而在=右边时,却使用了a,左边的a+1会先执行然后赋给a,
    但是进行a+1的时候,inner会先从局部名称空间中找a这个名称,找到有a,但是这个a是在a+1的后面。程序就会报以上的错。如果局部名称空间没有a,就会往上面的空间找。
    再找不到,就会报 a is not defined错误。
  • 相关阅读:
    反射
    关于EwebEeditor 不能上传图片问题解决方法
    js去掉前后空格
    园子开张
    使用Python 爬取 京东 ,淘宝。 商品详情页的数据。(避开了反爬虫机制)
    c#对于加密的一点整合 (AES,RSA,MD5,SHA256)
    移动战略调查:应用开发者首选微软Windows
    Surface Pro打包微软精华 今晚在华开售
    Ceph学习全过程 基于N版
    k8s中部署wordpress
  • 原文地址:https://www.cnblogs.com/KbMan/p/11173574.html
Copyright © 2020-2023  润新知