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())
  • 相关阅读:
    RMI几种公布和引用服务的方式
    mysql 多日志表结果集合拼接存储过程
    USRP通信的结构体和常量(上位机、下位机共用)
    Flash Builder4破解步骤
    leetcode 217 Contains Duplicate 数组中是否有反复的数字
    关于权限表的基本设计
    Objective-C之成魔之路【7-类、对象和方法】
    vs2008C1902程序数据库管理不匹配
    配置hadoop集群一
    BZOJ 2338 HNOI2011 数矩形 计算几何
  • 原文地址:https://www.cnblogs.com/qianslup/p/12188637.html
Copyright © 2011-2022 走看看