python 函数式编程 闭包,返回一个函数
参考链接:https://www.liaoxuefeng.com/wiki/1016959663602400/1017434209254976
作业
#使用生成器
def createCounter():
def count():
d=0
while True:
d+=1
yield d
c=count()
def f2():
return next(c)
return f2
#使用nonlocal关键字
def createCounter():
i=0
def count():
nonlocal i
i+=1
return i
return count
通常我们定义的函数都是返回函数的运行结果,但是假如我们不需要让这个函数立即执行,而是在后面某些情况下才执行,我们就可以定义一个函数,让这个函数返回我们需要执行的函数。
假设我们需要返回的函数是这样的:
def calc_sum(*args):
ax = 0
for n in args:
ax = ax + n
return ax
那么返回上面这个函数的函数就可以这样定义:
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum
定义一个返回函数的函数,只需要把原函数的参数挪到外面的函数中,然后原封不动的将里面的函数增加一个缩进使其符合缩进规则,最后把函数名在外面的函数中返回就好了
lazy_sum()
时,返回的并不是求和结果,而是求和函数:
>>> f = lazy_sum(1, 3, 5, 7, 9)
>>> f
<function lazy_sum.<locals>.sum at 0x101c6ed90>
当我们真正想要执行函数的时候,就加上括号,让函数运行
>>> f()
25
闭包
注意闭包不能接受参数,因为返回的是函数名,无法传递参数
在这个例子中,我们在函数lazy_sum
中又定义了函数sum
,并且,内部函数sum
可以引用外部函数lazy_sum
的参数和局部变量,当lazy_sum
返回函数sum
时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。
需要注意的是,当我们调用lazy_sum()
时,每次调用都会返回一个新的函数,每个函数的调用间不受影响。即使传入相同的参数:
>>> f1 = lazy_sum(1, 3, 5, 7, 9)
>>> f2 = lazy_sum(1, 3, 5, 7, 9)
>>> f1==f2
False
闭包的另一个问题,返回函数不要引用任何循环变量,或者会发生变化的变量
下面的返回的函数运行结果是一样的,并不是我们认为的1,4,9,而都是9
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs f1, f2, f3 = count()
>>> f1()
9
>>> f2()
9
>>> f3()
9
这是因为,返回的函数并没有立刻执行,而是直到调用了f()
才执行。等到3个函数都返回时,它们所引用的变量i
已经变成了3
,因此最终结果为9
。
返回的函数在其定义内部引用了局部变量args
,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用,所以,闭包用起来简单,实现起来可不容易。
返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
如果一定要引用循环变量呢?
方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:
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
缺点是代码较长,可利用lambda函数缩短代码。
python 函数式编程 闭包,返回一个函数的更多相关文章
- python函数式编程之返回函数、匿名函数、装饰器、偏函数学习
python函数式编程之返回函数 高阶函数处理可以接受函数作为参数外,还可以把函数作为结果值返回. 函数作为返回值 def laxy_sum(*args): def sum(): ax = 0; fo ...
- python 函数式编程:高阶函数,map/reduce
python 函数式编程:高阶函数,map/reduce #函数式编程 #函数式编程一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数 #(一)高阶函数 f=abs f print ...
- python函数式编程之高阶函数学习
基本概念 函数式编程,是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量.因此,任意一个函数,只要输入确定,输出就确定的这种函数我们称之为纯函数,我们称这种函数没有副作用.而允许使用 ...
- Python函数式编程:内置函数reduce 使用说明
一.概述 reduce操作是函数式编程中的重要技术之一,其作用是通过对一个集合的操作,可以从中生成一个值.比如最常见的求和,求最大值.最小值等都是reduce操作的典型例子.python通过内置red ...
- Python函数式编程:内置函数map()使用说明
一.概述 map操作是函数式编程中的重要技术之一,其作用就是对一个集合中的每个元素做处理,生成一个新的元素,由这些新的元素组成一个新的集合的返回. 所以map操作后,产生的新集合的元素个数和原集合的元 ...
- 【python】python函数式编程、高阶函数
1.map() : python内置的高阶函数,接收一个函数f和一个list,并通过把函数f依次作用在list的每个元素上,得到一个新的list并 返回. def f(x): r ...
- Python“函数式编程”中常用的函数
1.map(func,seq[,seq,...]) 对序列中的每个元素应用函数,python2中map()返回的是列表,python3中返回的是迭代器,可以用list()转换成列表.以下例子为pyth ...
- Learning Python 012 函数式编程 2 返回函数 匿名函数 装饰器 偏函数
Python 函数式编程 2 返回函数 返回函数的意思就是:函数作为返回值.(高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回.) 举个例子:实现一个可变参数的求和. 正常的函数: de ...
- Learning Python 012 函数式编程 1 高阶函数
Python 函数式编程 1 高阶函数 高阶函数 Q:什么是高阶函数? A:一个函数接收另一个函数作为参数,这种函数就称之为高阶函数. 简单举个例子: def add(x, y, f): return ...
随机推荐
- springcloud学习之路: (四) springcloud集成Hystrix服务保护
Hystrix是一套完善的服务保护组件, 可以实现服务降级, 服务熔断, 服务隔离等保护措施 使用它可以合理的应对高并发的情况 做到保护服务的效果 1. 导入依赖 <dependency> ...
- Linux进程管理 (篇外)内核线程简要介绍【转】
转自:https://www.cnblogs.com/arnoldlu/p/8336998.html 关键词:kthread.irq.ksoftirqd.kworker.workqueues 在使用p ...
- openstack Train 版本dashaboard 404问题
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明本文链接:https://blog.csdn.net/weixin_28738845/articl ...
- Unity检视面板的继承方法研究 (一)
对于检视面板 Inspector 的面板继承方式对项目来说是很有必要的, 比如一个基类, 写了一个很好看的检视面板[CustomEditor(typeof(XXX))], 可是所有子类的面板无法直接继 ...
- git stash 命令
摘自: http://blog.csdn.net/longxiaowu/article/details/26815433 关于git stash命令的使用方法网上一大把,我想记录的是我在使用过程中觉得 ...
- 201871010134-周英杰《面想对象程序设计(java)》第十一周学习总结
项目 内容 <面向对象程序设计(java)> https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/ ...
- pikachu 文件包含,上传,下载
一.文件包含 1.File Inclusion(local) 我们先测试一下,选择kobe然后提交 发现url出现变化 可以猜测此功能为文件包含,包含的文件为 file1.php,所以我在此盘符的根目 ...
- python3对urllib和urllib2进行了重构
python3对urllib和urllib2进行了重构,拆分成了urllib.request,urllib.response, urllib.parse, urllib.error等几个子模块,这样的 ...
- 洛谷 P3742 umi的函数
传送门 思路 \(loceaner\)已经蔡虚鲲到连红题都不会做了 因为有\(special\ judge\)所以我们就可以瞎搞了! 由题目可知,只要有一个\(y[i] > x[i]\)则一定没 ...
- [LeetCode] 415. Add Strings 字符串相加
Given two non-negative numbers num1 and num2 represented as string, return the sum of num1 and num2. ...