return编程python_python3 第二十一章 - 函数式编程之return函数和闭包

我们来实现一个可变参数的求和。通常情况下,求和的函数是这样定义的:

def calc_sum(*args):

ax=0for n inargs:

ax= ax +nreturn ax

但是,如果不需要立刻求和,而是在后面的代码中,根据需要再计算怎么办?可以不返回求和的结果,而是返回求和的函数:

def lazy_sum(*args):defsum():

ax=0for n inargs:

ax= ax +nreturnaxreturnsum

f= lazy_sum(1, 2, 3, 4)print(f)print(f())

以上代码,输出:

.sum at 0x1014476a8>

10

当我们调用lazy_sum()时,返回的并不是求和结果,而是求和函数,调用函数f时,才真正计算求和的结果。

在这个例子中,我们在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。

请再注意一点,当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数:

def lazy_sum(*args):defsum():

ax=0for n inargs:

ax= ax +nreturnaxreturnsum

f1= lazy_sum(1, 2, 3, 4)

f2= lazy_sum(1, 2, 3, 4)print('f1==f2 :', f1 == f2)

以上代码,输出:

f1==f2 : False

f1()和f2()的调用结果互不影响。

闭包(closure)是函数式编程的重要的语法结构。下面看一个闭包的实际例子:

defline_conf(a, b):defline(x):return a * x +breturnline

line1= line_conf(1, 2)

line2= line_conf(3, 7)print(line1(5), line2(5))

这个例子中,函数line与环境变量a,b构成闭包。在创建闭包的时候,我们通过line_conf的参数a,b说明了这两个环境变量的取值,这样,我们就确定了函数的最终形式(y = x + 2和y = 3x + 7)。我们只需要变换参数a,b,就可以获得不同的直线表达函数。由此,我们可以看到,闭包也具有提高代码可复用性的作用。

如果没有闭包,我们需要每次创建直线函数的时候同时说明a,b,x。这样,我们就需要更多的参数传递,也减少了代码的可移植性。利用闭包,我们实际上创建了泛函。line函数定义一种广泛意义的函数。这个函数的一些方面已经确定(必须是直线),但另一些方面(比如a和b参数待定)。随后,我们根据line_conf传递来的参数,通过闭包的形式,将最终函数确定下来。

闭包与并行运算

闭包有效的减少了函数所需定义的参数数目。这对于并行运算来说有重要的意义。在并行运算的环境下,我们可以让每台电脑负责一个函数,然后将一台电脑的输出和下一台电脑的输入串联起来。最终,我们像流 水线一样工作,从串联的电脑集群一端输入数据,从另一端输出数据。这样的情境最适合只有一个参数输入的函数。闭包就可以实现这一目的。这也是函数式编程又热起来的一个重要原因。函数式编程早在1950年代就已经存在,但应用并不广泛。然而,我们上面描述的流水线式的工作并行集群过程,正适合函数式编程。由于函数式编程这一天然优势,越来越多的语言也开始加入对函数式编程范式的支持。

需要注意的问题是,返回的函数并没有立刻执行,而是直到调用了f()才执行。我们来看一个例子:

defcount():

fs=[]for i in range(1, 4):deff():return i*i

fs.append(f)returnfs

f1, f2, f3=count()print('f1():', f1())print('f2():', f2())print('f3():', f3())

在上面的例子中,每次循环,都创建了一个新的函数,然后,把创建的3个函数都返回了。

你可能认为调用f1(),f2()和f3()结果应该是1,4,9,但实际结果是:

f1(): 9f2():9f3():9

全部都是9,原因就在于返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9。

返回函数不要引用任何循环变量,或者后续会发生变化的变量。如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:

defcount():deff(j):defg():return j *jreturng

fs=[]for i in range(1, 4):

fs.append(f(i))#f(i)立刻被执行,因此i的当前值被传入f()

returnfs

f1, f2, f3=count()print('f1():', f1())print('f2():', f2())print('f3():', f3())

以上代码,输出:

f1(): 1f2():4f3():9

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/378835.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

黑色背景下,计算照片白色的区域面积和周长

黑色背景下,计算照片白色的区域面积和周长 import cv2 img cv2.imread(E:\Python-workspace\OpenCV\OpenCV/beyond.png,1)#第一个参数为选择照片的路径,注意照片路径最后一个为正斜杠其他都为反斜杠;第二个参数,其中1表示所选照…

php连接mssql数据库的几种方式

数据库查询不外乎4个步骤,1、建立连接。2、输入查询代码。3、建立查询并取出数据。4、关闭连接。 php连接mssql数据库有几个注意事项,尤其mssql的多个版本、32位、64位都有区别。 首先,php.ini文件中;extensionphp_pdo_mssql.dll ;extensionp…

通俗易懂:快速理解P2P技术中的NAT穿透原理

目录1、基础知识1.1、什么是NAT?1.2、为什么会有NAT?1.3、NAT有什么优缺点?2、NAT的实现方式2.1、静态NAT2.2、NAPT3、NAT的主要类型3.1、完全锥型NAT(Full Cone NAT,后面简称FC)3.2、受限锥型NAT&#xff…

duration java_Java Duration类| toNanos()方法与示例

duration javaDuration Class toNanos()方法 (Duration Class toNanos() method) toNanos() method is available in java.time package. toNanos()方法在java.time包中可用。 toNanos() method is used to convert this Duration into the number of nanoseconds. toNanos()方…

java 负载均衡_java负载均衡 - 岁月静好I的个人空间 - OSCHINA - 中文开源技术交流社区...

作用对系统的高可用,网络压力的缓解,处理能力扩容的重要手段之一。服务器负载我们通常所说的负载是指:服务器负载软硬件负载服务器负载又分为:软件负载--硬件负载软件负载:通过在服务器上安装一些具有负载功能或模块的…

b tree和b+tree_B TREE实施

b tree和btreeB TREE及其操作简介 (Introduction to B TREE and its operations) A B tree is designed to store sorted data and allows search, insertion and deletion operation to be performed in logarithmic time. As In multiway search tree, there are so many nod…

黑色背景下,将照片内封闭空心图案的空心区域染成Cyan并保存

在黑色背景下,将照片内封闭空心图案的空心区域染色 import cv2 import numpy as np img cv2.imread(E:\Python-workspace\OpenCV\OpenCV/beyond.png,1)#第一个参数为选择照片的路径,注意照片路径最后一个为正斜杠其他都为反斜杠;第二个参数…

Ubuntu输入su提示认证失败的解决方法

Ubuntu输入su提示认证失败的解决方法 启动ubuntu服务时竟然提示权限不够,用su切换,输入密码提示认证失败,这下搞了吧,后来一经查阅原来Ubuntu安装后,root用户默认是被锁定了的,不允许登录,也不允…

SDP协议基本分析(RTSP、WebRTC使用)

目录一、介绍二、标准 SDP 规范1. SDP 的格式2. SDP 的结构(1)会话描述(2)媒体描述三、WebRTC 中的 SDP一、介绍 SDP(Session Description Protocal)以文本描述各端(PC 端、Mac 端、Android 端…

MFC六大关键技术(第四部分)——永久保存(串行化)

MFC 六大关键技术 ( 第四部分 ) ——永久保存(串行化) 先用一句话来说明永久保存的重要:弄懂它以后,你就越来越像个程序员了! 如果我们的程序不需要永久保存,那几乎可以肯定是一个小玩儿。那怕我们的记事本…

在网络中配置思科交换机

By default, all ports of a switch are enabled. As we are talking about layer 2 switching, there is no need to configure IP address or any routing protocol on the switch. In such a situation, the configuration is not focused on the switch. 缺省情况下&#…

黑色背景下,描绘照片的轮廓形状并保存

描绘照片的轮廓形状并保存 import cv2 from matplotlib import pyplot as plt # 1.先找到轮廓 img cv2.imread(E:\Python-workspace\OpenCV\OpenCV/beyond.png, 0) _, thresh cv2.threshold(img, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) image, conturs, hierarchy c…

java pdf合并_Java 合并、拆分PDF文档

本文将介绍如何在Java程序中合并及拆分PDF文档,合并文档时,包括合并多个不同PDF文档为一个文档,以及合并PDF文档的不同页面为一页;拆分文档是,包括将PDF文档按每一页拆分,以及按指定页数范围来拆分。下面将…

HDU4405 期望

对于期望,首先,对于这个公式中p表示概率,x表示随机变量 展开则为 ex p1*x1p2*x2p3*x3....... 对于本题 假设 ex[ i ]表示当前 i 走到 n 的期望值。所以若 i 处没有飞机,ex[ i ]sigma(1/6*ex[ik])1 其中(k1...6) (1表示…

调用本地电脑摄像头并进行按P进行捕获照片并保存,按下Q退出

调用本地电脑摄像头并进行按P进行捕获照片并保存,按下Q退出 灰度摄像头显示: import cv2 cap cv2.VideoCapture(0) if not cap.isOpened():print("Cannot open camera")exit() while True:# 逐帧捕获ret, frame cap.read()# 如果正确读取帧…

intersect函数_PHP array_intersect()函数与示例

intersect函数PHP array_intersect()函数 (PHP array_intersect() Function ) array_intersect() function is used to find the matched elements from two or more elements. Function “array_intersect()” compares the values of the first array with the other arrays …

很全的SQL注入语句

1、返回的是连接的数据库名and db_name()>02、作用是获取连接用户名and user>03、将数据库备份到Web目录下面;backup database 数据库名 to diskc:\inetpub\wwwroot\1.db;--4、显示SQL系统版本and 1(select VERSION) 或and 1convert(int,version)--5、判断xp_cmdshell扩展…

使用DataTable更新数据库

1、修改数据 DataRow dr hRDataSet.Tables["emp"].Rows.Find(textBox3.Text);//DataRow dr hRDataSet.Tables["emp"].Select("id"textBox3.Text)[0];dr.BeginEdit();dr["name"] textBox1.Text;dr.EndEdit();SqlCommandBuilder cmdn…

java异常体系_JAVA异常体系结构详解

一、什么是异常异常:程序在运行过程中发生由于硬件设备问题、软件设计错误等导致的程序异常事件。(在Java等面向对象的编程语言中)异常本身是一个对象,产生异常就是产生了一个异常对象。 ——百度百科二、异常体系Java把异常当作对象来处理&#xf…

对照片质量进行压缩

对照片质量进行压缩 其实无论是jpg还是png都是已经压缩编码化的格式罢了,原图片的大小要远远大于压缩编码后的格式 1,像素:图片放大到一定程度之后的一个个的小方块 2,RGB:每一个像素(小方块)都…