• python中的闭包


    一 .定义
      如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).这个定义是相对直白的,

    闭包有三个条件:

      1.函数嵌套 

      2,内部函数调用外部函数的变量 

      3.返回内部函数

    def a(a):
        def B(b):
            s = a + b
            return s
        return B
    cd =a(6)
    ss = cd(4)
    print(ss)#结果为10

     二 闭包中注意的事项

      闭包中是不能修改外部作用域的局部变量的值

    1 def foo():  
    2     m = 0  
    3     def foo1():  
    4         m = 1  
    5         print(m)  
    6     print(m)  
    7     foo1()  
    8     print(m)
    9 foo()  

    ###########################
    0
    1
    0

    以下这段代码是在python中使用闭包时一段经典的错误代码

    这段程序的本意是要通过在每次调用闭包函数时都对变量a进行递增的操作。但在实际使用时

    def foo():  
        a = 1  
        def bar():  
            a = a + 1  
            return a  
        return bar 

      这是因为在执行代码 c = foo()时,python会导入全部的闭包函数体bar()来分析其的局部变量,python规则指定所有在赋值语句左面的变量都是局部变量,则在闭包bar()中,变量a在赋值符号"="的左面,被python认为是bar()中的局部变量。再接下来执行print c()时,程序运行至a = a + 1时,因为先前已经把a归为bar()中的局部变量,所以python会在bar()中去找在赋值语句右面的a的值,结果找不到,就会报错。解决的方法很简单,使用语句nonloacal a就可以了,该语句显式的指定a不是闭包的局部变量。

    方法一

    def foo():  
        a = [1]  
        def bar():  
            a[0] = a[0] + 1  
            return a[0]  
        return bar 

    方法二

    def foo():  
        a = 1  
        def bar():
            nonlocal a  
            a = a + 1  
            return a  
        return bar  
    c = foo()
    print(c())

    经典错误问题:

    flist = []  
    for i in range(3):  
        def foo(x): 
    print x + i flist.append(foo) for f in flist: f(2)

      可能有些人认为这段代码的执行结果应该是2,3,4.但是实际的结果是4,4,4。这是因为当把函数加入flist列表里时,python还没有给i赋值,只有当执行时,再去找i的值是什么,这时在第一个for循环结束以后,i的值是2,所以以上代码的执行结果是4,4,4.解决方法也很简单,改写一下函数的定义就可以了。

    for i in range(3):  
        def foo(x,y=i): 
            print x + y  
        flist.append(foo)        

    三 闭包的用途

      1 .当闭包执行完后,仍然能够保持住当前的运行环境。

      2.闭包可以根据外部作用域的局部变量来得到不同的结果,这有点像一种类似配置功能的作用,我们可以修改外部的变量,闭包根据这个变量展现出不同的功能。

    1 def make_filter(keep):  
    2     def the_filter(file_name):  
    3         file = open(file_name)  
    4         lines = file.readlines()  
    5         file.close()  
    6         filter_doc = [i for i in lines if keep in i]  
    7         return filter_doc  
    8     return the_filter

    如果我们需要取得文件"result.txt"中含有"pass"关键字的行,则可以这样使用例子程序
    filter = make_filter("pass")  
    filter_result = filter("result.txt") 
  • 相关阅读:
    我是卡拉 上海国际工业博览会纪实(4)
    GDI+中常见的几个问题(1)
    我是卡拉 上海国际工业博览会纪实(2)
    GDI+中常见的几个问题(9)
    GDI+中常见的几个问题(3)
    我是卡拉 上海国际工业博览会纪实(7)
    贵阳的小吃
    Indigo是啥
    我是卡拉 上海国际工业博览会纪实(3)
    云计算里AWS和Azure的探究(1)
  • 原文地址:https://www.cnblogs.com/taysem/p/10821908.html
Copyright © 2020-2023  润新知