python基础——返回函数  

函数作为返回值

  高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回

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

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时,才真正计算求和的结果:

>>> 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

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

闭包

  注意到返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用,所以,闭包用起来简单,实现起来可不容易。

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

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

  

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

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

>>> f1()
9
>>> f2()
9
>>> f3()
9

  全部都是9原因就在于返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量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

  

  缺点是代码较长,可利用lambda函数缩短代码。

小结

  一个函数可以返回一个计算结果,也可以返回一个函数

   返回一个函数时,牢记该函数并未执行,返回函数中不要引用任何可能会变化的变量

python基础——返回函数的更多相关文章

  1. python基础——匿名函数

    python基础——匿名函数 当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便.  在Python中,对匿名函数提供了有限支持.还是以map()函数为例,计算f(x)=x2时 ...

  2. python基础——sorted()函数

    python基础——sorted()函数 排序算法 排序也是在程序中经常用到的算法.无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小.如果是数字,我们可以直接比较,但如果是字符串或者两个d ...

  3. python基础——filter函数

    python基础——filter函数 Python内建的filter()函数用于过滤序列. 和map()类似,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函 ...

  4. python基础——匿名函数及递归函数

    python基础--匿名函数及递归函数 1 匿名函数语法 匿名函数lambda x: x * x实际上就是: def f(x): return x * x 关键字lambda表示匿名函数,冒号前面的x ...

  5. 八. Python基础(8)--函数

    八. Python基础(8)--函数 1 ● 函数返回布尔值 注意, 自定义的函数也可以是用来作逻辑判断的, 例如内置的startswith()等函数. def check_len(x):     ' ...

  6. python基础之函数详解

    Python基础之函数详解 目录 Python基础之函数详解 一.函数的定义 二.函数的调用 三.函数返回值 四.函数的参数 4.1 位置参数 4.2 关键字参数 实参:位置实参和关键字参数的混合使用 ...

  7. python基础之函数进阶之函数作为返回值/装饰器

    因为装饰器需要用到返回函数的知识,所以在这里将返回函数和装饰器合并讲解. 什么是返回函数? 我们知道,一个函数中return可以返回一个或者多个值,但其实,return不仅可以返回值,还可以返回函数. ...

  8. Python学习笔记(一)python基础与函数

    1.python基础 1.1输入与输出 输出 用print加上字符串,就可以打印指定的文字或数字 >>> print 'hello, world' hello, world > ...

  9. Day3 - Python基础3 函数、递归、内置函数

    Python之路,Day3 - Python基础3   本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8. ...

随机推荐

  1. 如何查看华为EMUI系统APK源码?

    最近想看一下华为EMUI里面的某些系统APK是如何实现的. 那如何获取系统APK呢? 有两种方式: 1.安装豌豆荚,豌豆荚里有一个应用管理的功能,可以查看手机里的所有应用,包括系统应用. 可以使用该功 ...

  2. 用CSS画个三角形

    <!DOCTYPE html> <html> <head> <style type="text/css"> #trangle { d ...

  3. word文档的生成、修改、渲染、打印,使用Aspose.Words

    无需MS Word也可执行各种文档处理任务,包括文档的生成.修改.渲染.打印,文档格式转换和邮件合并等文档处理.

  4. web安全及防护

    本文将对web方面的安全问题以及相应的防护方法进行一个简单的介绍. SQL注入(SQL Injection) 原理:就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺 ...

  5. linux u-boot跟踪方法总结

    拿到一块板子,其中很重要的一项就是看电路图还有Datasheet. 这个真的很重要,首先你要知道cpu的架构是什么,armv7?arvmv5?还是其他的,哪个公司的芯片?是freescale 还是TI ...

  6. 2016年11月2日--Window.document对象

    一.找到元素: docunment.getElementById("id"):                      根据id找,最多找一个: var a =docunment ...

  7. 浏览器js自动查表脚本

    javascript: void((function() {$.get("", {wen: "880350384879600241",action: " ...

  8. Design Elevator

    From: https://discuss.leetcode.com/topic/89/write-elevator-program-using-event-driven-programming/9 ...

  9. js弹出提示信息,然后跳转到另一页面

    <script language="javascript">  alert("您的用户名与密码已成功修改!");  document.locatio ...

  10. iOS FMDB 不需要关闭

    以前做了一个应用,里面用到了FMDB,进行每一次操作前,都open,完成操作后都close.因为我是参考他们以前的代码.程序初期没发现什么问题,程序完成后,各种卡顿就出现了!即使我是放在新线程里操作的 ...