python学习之路(18)
返回函数
函数作为返回值
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。
我们来实现一个可变参数的求和。通常情况下,求和的函数是这样定义的:
>>> def a(*args):
ax=
for n in args:
ax =ax+n
return ax >>> a([,,])
Traceback (most recent call last):
File "<pyshell#6>", line , in <module>
a([,,])
File "<pyshell#5>", line , in a
ax =ax+n
TypeError: unsupported operand type(s) for +: 'int' and 'list'
>>> a(,,,)
这里不能用list传参 注意是*args
但是,如果不需要立刻求和,而是在后面的代码中,根据需要再计算怎么办?可以不返回求和的结果,而是返回求和的函数!
>>> def a(*args):
def sum():
ax=
for n in args:
ax=ax+n
return ax
return sum
当我们调用a()时,返回的并不是求和结果,而是求和函数:调用函数s时,才真正计算求和的结果:
>>> s=a(,)
>>> s
<function a.<locals>.sum at 0x05D14C00>
>>> s()
在这个例子中,我们在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。
请再注意一点,当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数:
>>> s1=a(1,2)
>>> s2=a(1,2)
>>> s1==s2
False
s1()和s2()的调用结果互不影响。
闭包
注意到返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用,所以,闭包用起来简单,实现起来可不容易。
另一个需要注意的问题是,返回的函数并没有立刻执行,而是直到调用了f()才执行。我们来看一个例子:
>>> def p():
fs=[]
for i in range(,):
def f():
return i*i
fs.append(f)
return fs >>> f1,f2,f3 =count()
Traceback (most recent call last):
File "<pyshell#39>", line , in <module>
f1,f2,f3 =count()
NameError: name 'count' is not defined
>>> f1,f2,f3 =p()
>>> f1() >>> f2() >>> f3()
全部都是9!原因就在于返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9。
返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:
>>> def count():
fs=[]
for i in range(,):
def f(j):
def g():
return j*j
return g
fs.append(f(i))
return fs >>> f1=count()
>>> f1()
Traceback (most recent call last):
File "<pyshell#33>", line , in <module>
f1()
TypeError: 'list' object is not callable
>>> f1, f2, f3 = count()
SyntaxError: unexpected indent
>>> f1, f2, f3 = count()
>>> f1() >>> f2() >>> f3()
对于@塔塔gogo的例子,说白了就是i是公共的,j是私有的。也就是
i=1
j=i #f1可使用这个j,以及公共的i
i=2
j=i #f2可使用这个j,以及公共的i
i=3
j=i #f3可使用这个j,以及公共的i
虽然表面上看有3个j,然而这3个j在内存中具有不同的地址,而公共的i只有一个地址。
最后计算f1()时,虽然此时i=3,但是f1中的j为1,从而得到结果1;同理f2()为4,f3()为9.
下面将这个程序稍作修改,结果显而易见。
count()中存放的是三个f函数,当调用f1,f2,f3 = count()时,此时的for循环结束了,i=3.再执行f1()的时候相当于执行下面: i=3 def f(): return i*i 这个时候的值为9.
其实count()执行后,是返回一个这样的list【g(j1),g(j2),g(j3)】,而不是【f(j1),f(j2),f(j3)】。然后>>> f1, f2, f3 = count()分别指向list中的每个元素。
lambda简化函数
f1, f2, f3 = map(lambda y : (lambda : y * y), range(1,4))
python学习之路(18)的更多相关文章
- Python学习之路【第一篇】-Python简介和基础入门
1.Python简介 1.1 Python是什么 相信混迹IT界的很多朋友都知道,Python是近年来最火的一个热点,没有之一.从性质上来讲它和我们熟知的C.java.php等没有什么本质的区别,也是 ...
- python学习之路-day2-pyth基础2
一. 模块初识 Python的强大之处在于他有非常丰富和强大的标准库和第三方库,第三方库存放位置:site-packages sys模块简介 导入模块 import sys 3 sys模 ...
- Python学习之路-Day2-Python基础3
Python学习之路第三天 学习内容: 1.文件操作 2.字符转编码操作 3.函数介绍 4.递归 5.函数式编程 1.文件操作 打印到屏幕 最简单的输出方法是用print语句,你可以给它传递零个或多个 ...
- Python学习之路-Day2-Python基础2
Python学习之路第二天 学习内容: 1.模块初识 2.pyc是什么 3.python数据类型 4.数据运算 5.bytes/str之别 6.列表 7.元组 8.字典 9.字符串常用操作 1.模块初 ...
- Python学习之路-Day1-Python基础
学习python的过程: 在茫茫的编程语言中我选择了python,因为感觉python很强大,能用到很多领域.我自己也学过一些编程语言,比如:C,java,php,html,css等.但是我感觉自己都 ...
- python学习之路网络编程篇(第四篇)
python学习之路网络编程篇(第四篇) 内容待补充
- python 学习之路开始了
python 学习之路开始了.....记录点点滴滴....
- python学习之路,2018.8.9
python学习之路,2018.8.9, 学习是一个长期坚持的过程,加油吧,少年!
- Python学习之路——pycharm的第一个项目
Python学习之路——pycharm的第一个项目 简介: 上文中已经介绍如何安装Pycharm已经环境变量的配置.现在软件已经安装成功,现在就开始动手做第一个Python项目.第一个“Hello W ...
- python学习之路------你想要的都在这里了
python学习之路------你想要的都在这里了 (根据自己的学习进度后期不断更新哟!!!) 一.python基础 1.python基础--python基本知识.七大数据类型等 2.python基础 ...
随机推荐
- js创建jsonArray传输至后台及后台解析
//产品清单 //产品数量长度 var cnbvLength = FieldCount9 + 1; var arrayList=[]; for(var i = 0; i < cnbvLength ...
- 大数据学习(1)-shell脚本注意事项
1.变量=值 (例如STR=abc) 不用加引号,但此时空格不再是空格字符,特殊字符可用于转义 2.等号两侧不能有空格 3.变量名称一般习惯为大写 4.双引号和单引号有区别,双引号仅将空格脱意,单引 ...
- thinkphp3.2.3 自动验证 unique 出错的解决办法
场景:修改数据时,唯一验证name字段出错,提示已存在. 排查: 1.传入的参数是否包含主键,因为 D('模型名')->create() 会自动判断是否是新增或者修改,根据传入的参数判断是否包含 ...
- vue实现登录路由拦截
第一步 在router.js里面 把需要判断是否登录的路由添加meta对象属性 在meta对象里面自定义一个属性值 第二步 : 在router.js里面 与const router = new Rou ...
- leetcode240 搜索二维矩阵 II
题目: 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target.该矩阵具有以下特性: 每行的元素从左到右升序排列. 每列的元素从上到下升序排列. 示例: 现有矩阵 ma ...
- qq游戏IE组件停止工作
你可以下载一个腾讯电脑管家,利用电脑诊所里的腾讯游戏专区里的“网页游 游戏玩不了”这一项修复一下即可.我遇见一次,修复之后就解决了.个人认为是Adobe Flash出问题了.祝你玩的开心.
- Linux排查磁盘空间顺序解决空间不足问题
1 先查看整个磁盘的情况 df -h 查看整台服务器的硬盘使用情况 cd / 进入根目录 du -s ...
- 制作嵌入式linux内核
拿到一个嵌入式linux内核代码,首先make distclean 接下来,如果在x86平台,就直接make menuconfig,如果是在ARM平台,就直接make menuconfig ARCH= ...
- DNS信息探测
前面学习一下DNS域名解析原理及过程,今天我们学习下DNS域名信息的探测 本章主要目标是从各个角度搜集测试目标的基本信息,包括搜集信息的途径.各种工具的使用方法,以及简单的示例. 0x00 DNS信息 ...
- IDA Pro - 使用IDA Pro逆向C++程序
原文地址:Reversing C++ programs with IDA pro and Hex-rays 简介 在假期期间,我花了很多时间学习和逆向用C++写的程序.这是我第一次学习C++逆向,并且 ...