首先,来看一个一般意义的求和:

>>> def cal_sum(*args):
... sum = 0
... for i in args:
... sum = sum + i
... return sum
...
>>> cal_sum(1,2,3,4)
10

如果我们这么定义呢:

>>> def lazy_sum(*args):
... def sum():
... sum = 0
... for i in args:
... sum = sum + i
... return sum
... return sum
...
>>> l = lazy_sum(1,2,3,4)
>>> l
<function lazy_sum.<locals>.sum at 0x00E4A198>

我们发现,这种定义的函数,返回的并不是一个具体的求和,而是一个函数!来看看怎么调用这个函数:

>>> l()
10

在这个例子中,lazy_sum中又定义了一个函数sum(),这个内部函数可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这就是‘闭包’。

再来试验一下:

>>> l1=lazy_sum(1,2,3,4)
>>> l2=lazy_sum(1,2,3,4)
>>> l1==l2
False

我们发现,l1和l2互不影响!这说明lazy_sum每次调用都返回一个新函数,即使传入的参数相同。

其实,返回的函数在其定义的内部引用了局部变量args,当一个函数返回了一个函数后,其内部的局部变量还能被新函数引用。另外,返回的函数并没有立即被执行,而是直到调用了l()后才执行。通过下面的例子再来加深一下印象

例子1:

>>> def count():
... f = []
... for i in range(1,4):
... def fp():
... return i * i
... f.append(fp)
... return f
...
>>> f1,f2,f3 = count()
>>> f1()
9
>>> f2()
9
>>> f3()
9

全部都是9,并不是1,4,9.原因在于返回的函数引用了变量i,但它并没有立即执行。等三个函数都返回时,他们所引用的变量i已经变成了3,所以最终结果都是9。由此,我们要注意:以后为了避免出现乱七八糟的数据错误,返回函数不要引用任何的循环变量,或者后续会发生变化的变量。

这时你要说了,如果一定要引用循环变量,怎么办呢?方法是再创建一个函数,用该函数的参数绑定循环变量的当前值,那么无论该循环后续如何更改,已经绑定的函数参数的值都不变了:

>>> def count():
... def f(j):
... def g():
... return j*j
... return g
... fs = []
... for i in range(1,4):
... fs.append(f(i)) #f(i)立即被执行,变量i的当前值被传入f()
... return fs
...
>>> f1,f2,f3 = count()
>>> f1()
1
>>> f2()
4
>>> f3()
9

python高阶函数——返回函数(闭包)的更多相关文章

  1. python 高阶内置函数

    1.lambda 匿名函数 lambda 参数: 返回值 函数名统一都叫lambda. 2.sorted() 排序函数 排序函数 sorted(iterable,key,reverse) key:排序 ...

  2. Python高阶函数及函数柯里化

    1 Python高阶函数 接收函数为参数,或者把函数作为结果返回的函数为高阶函数. 1.1 自定义sort函数 要求:仿照内建函数sorted,自行实现一个sort函数.内建函数sorted函数是返回 ...

  3. Python高阶函数_map/reduce/filter函数

    本篇将开始介绍python高阶函数map/reduce/filter的用法,更多内容请参考:Python学习指南 map/reduce Python内建了map()和reduce()函数. 如果你读过 ...

  4. python——高阶函数:高阶函数

    python高阶函数 00初识高阶函数 一等公民 函数在python中是一等公民(First-Class Object),同样和变量一样,函数也是对象,只不过是可调用的对象,所以函数也可以作为一个普通 ...

  5. python高阶函数的使用

    目录 python高阶函数的使用 1.map 2.reduce 3.filter 4.sorted 5.小结 python高阶函数的使用 1.map Python内建了map()函数,map()函数接 ...

  6. python 高阶函数之filter

    前文说到python高阶函数之map,相信大家对python中的高阶函数有所了解,此次继续分享python中的另一个高阶函数filter. 先看一下filter() 函数签名 >>> ...

  7. 用一个简单的例子来理解python高阶函数

    ============================ 用一个简单的例子来理解python高阶函数 ============================ 最近在用mailx发送邮件, 写法大致如 ...

  8. python函数式编程之返回函数、匿名函数、装饰器、偏函数学习

    python函数式编程之返回函数 高阶函数处理可以接受函数作为参数外,还可以把函数作为结果值返回. 函数作为返回值 def laxy_sum(*args): def sum(): ax = 0; fo ...

  9. Python高阶用法总结

    目录 1. lambda匿名函数 1.1 函数式编程 1.2 应用在闭包 2. 列表解析式 3. enumerate内建函数 4. 迭代器与生成器 4.1 迭代器 4.3 生成器 5. 装饰器 前言: ...

  10. JS进阶-特殊形式的函数-返回函数的函数/重写自己的函数

    返回函数的函数 // 返回函数的函数 function a() { alert("aa"); return function () { alert("bb"); ...

随机推荐

  1. js表达式和语句趣味题讲解与技术分享

    技术分享 问题1 { a: 1 } + 1 // ? ({ a: 1 }) + 1 // ? 1 + { a: 1 } // ? 答案 { a: 1 } + 1 // 1 ({ a: 1 }) + 1 ...

  2. .Net Core的API网关Ocelot使用 (一)

    1.什么是API网关 API网关是微服务架构中的唯一入口,它提供一个单独且统一的API入口用于访问内部一个或多个API.它可以具有身份验证,监控,负载均衡,缓存,请求分片与管理,静态响应处理等.API ...

  3. ggplot2|玩转Manhattan图-你有被要求这么画吗?

    本文首发于“生信补给站”,ggplot2|玩转Manhattan图-你有被要求这么画吗?更多关于R语言,ggplot2绘图,生信分析的内容,敬请关注小号. Manhattan图算是GWAS分析的标配图 ...

  4. 移动开发在路上-- IOS移动开发系列 网络交互四(1)

    最近一段时间上班忙的没日没夜的,不是披星戴月,就是头天早上出门,第二天早上回家...一直没出处时间来更新博客,码农之苦,说了都是泪,废话不多说,直接本主题,经过之前三篇的讲述,ios开发的东西大家或多 ...

  5. 第6节:Java基础 - 三大集合(上)

    第6节:Java基础 - 三大集合(上) 本小节是Java基础篇章的第四小节,主要介绍Java中的常用集合知识点,涉及到的内容包括Java中的三大集合的引出,以及HashMap,Hashtable和C ...

  6. 基于iCamera测试高清摄像头SIV100B(替代ov7670)小结

    基于iCamera测试高清摄像头SIV100B(替代ov7670)小结 先看看siv100b主要关键参数 SIV100B与OV7670分辨率和基本特性都差不多,而siv100b,像素尺寸更小,灵敏度更 ...

  7. Django 10

    目录 cookie和session cookie session token Django中间件 自定义中间件 process_request process_response 其他方法 cookie ...

  8. 大数据学习笔记——Hbase高可用+完全分布式完整部署教程

    Hbase高可用+完全分布式完整部署教程 本篇博客承接上一篇sqoop的部署教程,将会详细介绍完全分布式并且是高可用模式下的Hbase的部署流程,废话不多说,我们直接开始! 1. 安装准备 部署Hba ...

  9. 6种微服务RPC框架,你知道几个?

    开源 RPC 框架有哪些呢? 一类是跟某种特定语言平台绑定的,另一类是与语言无关即跨语言平台的. 跟语言平台绑定的开源 RPC 框架主要有下面几种. Dubbo:国内最早开源的 RPC 框架,由阿里巴 ...

  10. 非线性函数的最小二乘拟合及在Jupyter notebook中输入公式 [原创]

    突然有个想法,能否通过学习一阶RC电路的阶跃响应得到RC电路的结构特征——时间常数τ(即R*C).回答无疑是肯定的,但问题是怎样通过最小二乘法.正规方程,以更多的采样点数来降低信号采集噪声对τ估计值的 ...