zoukankan      html  css  js  c++  java
  • 闭包

    参考:https://www.cnblogs.com/Lin-Yi/p/7305364.html

    参考:https://www.cnblogs.com/JohnABC/p/4076855.html

    一、定义

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

    闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)(想想Erlang的外层函数传入一个参数a, 内层函数依旧传入一个参数b, 内层函数使用a和b, 最后返回内层函数)。

    这个从字面上很难理解,结合例子来看。

    def addx(x):  
        def adder(y): return x + y  
        return adder  

    在这段程序中,函数adder(y)是函数addx(x)的内嵌函数,并且是addx(x)函数的返回值。我们注意到一个问题:内嵌函数adder(y)中 引用到外层函数中的局部变量x。

    如果在一个内部函数里:adder(y)就是这个内部函数,
    对在外部作用域(但不是在全局作用域)的变量进行引用:x就是被引用的变量,x在外部作用域addx里面,但不在全局作用域里,
    则这个内部函数adder就是一个闭包。

    二、注意事项

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

    def fout():
        m = 0
        def finn():
            m = 1
            print(m)
        print(m)
        finn()
        print(m)        # 未改变m的值
    
    fout()

    2.2  未定义便引用

    def fout():
        a = 1
    
        def finn():
            a = a + 1      # 出错
            return a
        return finn
    
    
    t = fout()
    print(t())

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

    解决的方法一:将a定义为可变数据类型。

    def fout():
        a = [1]
    
        def finn():
            a[0] = a[0] + 1      # 未出错
            return a[0]
        return finn
    
    
    t = fout()
    print(t())

    解决方法二:对a进行变量声明

    def fout():
        a = 1
    
        def finn():
            nonlocal a
            a += 1
            return a
        return finn
    
    
    t = fout()
    print(t())
  • 相关阅读:
    数据结构学习(一)、线性表
    内容太多用省略号代替、内容不换行,鼠标移上去显示详情
    时间格式化
    51Nod--1018排序
    51Nod--1085背包问题
    51Nod--1049最大子段和
    51Nod--1051最大子矩阵和(DP入门)
    POj1852--Ants
    c# static用法
    group by用法
  • 原文地址:https://www.cnblogs.com/qianslup/p/12188637.html
Copyright © 2011-2022 走看看