我的机器学习教程「美团」算法工程师带你入门机器学习  以及 「三分钟系列」数据结构与算法  已经开始更新了,欢迎大家订阅~这篇专栏整合了这几年的算法知识,简单易懂,也将是我实体书的BLOG版。

欢迎大家扫码关注微信公众号「图灵的猫」,除了有更多AI、算法、Python相关文章分享,还有免费的SSR节点和外网学习资料。其他平台(微信/知乎/B站)也是同名「图灵的猫」,不要迷路哦~

今天在慕课网刷廖老师的Python进阶课程,有道题很有意思,题目是这样的:

在函数内部定义的函数和外部定义的函数是一样的,只是他们无法被外部访问:

def g():print 'g()...'def f():print 'f()...'return g

 g 的定义移入函数 f 内部,防止其他代码调用 g

def f():print 'f()...'def g():print 'g()...'return g

但是,考察上一小节定义的 calc_sum 函数:

def calc_sum(lst):def lazy_sum():return sum(lst)return lazy_sum

注意: 发现没法把 lazy_sum 移到 calc_sum 的外部,因为它引用了 calc_sum 的参数 lst

像这种内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)

闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变。举例如下:

# 希望一次返回3个函数,分别计算1x1,2x2,3x3:
def count():fs = []for i in range(1, 4):def f():return i*ifs.append(f)return fsf1, f2, f3 = count()
def count():fs = []for i in range(1, 4):def f():return i*ifs.append(f)return fsf1, f2, f3 = count()

你可能认为调用f1(),f2()和f3()结果应该是1,4,9,但实际结果全部都是 9(请自己动手验证)。

原因就是当count()函数返回了3个函数时,这3个函数所引用的变量 i 的值已经变成了3。由于f1、f2、f3并没有被调用,所以,此时他们并未计算 i*i,当 f1 被调用时:

>>> f1()
9     # 因为f1现在才计算i*i,但现在i的值已经变为3 # 因为f1现在才计算i*i,但现在i的值已经变为3

因此,返回函数不要引用任何循环变量,或者后续会发生变化的变量。

然后有位评论给出的见解我觉得非常厉害,他说,问题的产生是因为函数只在执行时才去获取外层参数i,若函数定义时可以获取到i,问题便可解决。而默认参数正好可以完成定义时获取i值且运行函数时无需参数输入的功能,所以在函数f()定义中改为f(m = i),函数f返回值改为m*m即可。

因此,改写后的函数应该为

def count():
    fs = []
    for i in range(1, 4):
        def new(j = i):
            return j * j
        fs.append(new)
    return fs

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

Python中的闭包与参数引用域相关推荐

  1. Python 中的闭包、匿名函数、decorator 装饰器与python的偏函数

    Python中的闭包 def calc_sum(lst):def lazy_sum():return sum(lst)return lazy_sum 像这种内层函数引用了外层函数的变量(参数也算变量) ...

  2. python闭包的应用场景_简单谈谈Python中的闭包

    Python中的闭包 前几天又有人留言,关于其中一个闭包和re.sub的使用不太清楚.我在脚本之家搜索了下,发现没有写过闭包相关的东西,所以决定总结一下,完善Python的内容. 1. 闭包的概念 首 ...

  3. Python中的闭包

    (如转载,请注明出处,谢谢.) 闭包这个概念在很多语言中都有涉及,本文主要谈谈python中的闭包.Python中使用闭包主要是在进行函数式开发时使用. 一,定义 python中的闭包从表现形式上定义 ...

  4. Python 中的闭包介绍

    引言 闭包是优雅的 Python 结构.在本文中,我们将了解它们,如何定义闭包,为什么以及何时使用它们. 但是在讨论什么是闭包之前,我们必须首先理解什么是嵌套函数,以及作用域规则是如何为它们工作的.那 ...

  5. 什么是闭包及Python中的闭包

    什么是闭包 Objects are data with methods attached. Closures are functions with data attached. 一般来说,我们都非常熟 ...

  6. python中的闭包(closure)

    背景 本文尝试介绍Python中的闭包(closure),包括闭包是什么? 为什么要使用闭包?如何使用闭包? 嵌套函数及非局部变量 在介绍闭包之前,需要先明白什么是嵌套函数和非局部变量.在一个函数(f ...

  7. python中什么是可变参数_详解Python的三种可变参数

    详解Python的三种可变参数 可变参数 可变参数应该最简单,在C/C++和Java等语言中都有,就是用*号来表示,例如 def testArg(*arg) 你可以传入任意多个元素(包括0)到参数中, ...

  8. python闭包与装饰器有啥关系_深入理解Python中的闭包与装饰器

    函数的装饰器可以以某种方式增强函数的功能,如在 Flask 中可使用 @app.route('/') 为视图函数添加路由,是一种十分强大的功能.在表现形式上,函数装饰器为一种嵌套函数,这其中会涉及到闭 ...

  9. Python中的闭包总结

    前几天又有人在我的这篇文章 python项目练习一:即时标记 下留言,关于其中一个闭包和re.sub的使用不太清楚.我在自己的博客上搜索了下,发现没有写过闭包相关的东西,所以决定总结一下,完善博客上P ...

  10. python闭包和装饰器的区别_深入理解Python中的闭包与装饰器

    函数的装饰器可以以某种方式增强函数的功能,如在 Flask 中可使用 @app.route('/') 为视图函数添加路由,是一种十分强大的功能.在表现形式上,函数装饰器为一种嵌套函数,这其中会涉及到闭 ...

最新文章

  1. C#+Mapxtreme 实现一些GIS系统基本的功能
  2. redis批量操作及性能分析
  3. 使用R画桑基图(流程图)
  4. sobel算子_OpenCV 学习:4 Sobel算子
  5. WPF 用代码实现WrapPanel右侧自动对齐(解决多余空白问题)
  6. Android 中流量、电量、弱网环境怎么测?
  7. 通过wifi使用nfs把ubuntu挂载到android
  8. httpClient4 设置代理
  9. ES索引重建reindex详解
  10. Python:存取npy格式数据
  11. TRACE32——List源代码查看
  12. darknet源码解析:networ结构体之input_pinned_gpu
  13. CCW:浪潮云+智能协同云平台获评“用户首选品牌”
  14. MacBook Pro做为Windows电脑的扩展屏【已解决】
  15. 不一样的课程表,不一样的Excle--用Excle进行设计(42):排序所演绎的数据逻辑
  16. Java学习之路-开局
  17. 乐优商城:笔记(六):上传微服务:LyUpload
  18. 网站常用的favicon.ico文件
  19. 最新电脑CPU天梯图
  20. jenkins自动化_通过Jenkins自动化PSR合规性

热门文章

  1. Javascript位置 body之前、后执行顺序
  2. 数据库的水平扩展与垂直扩展
  3. 模仿Google搜索功能
  4. EGit(Git Eclipse Plugin)使用
  5. LC-130 被环绕区域
  6. mysql 开启binlog
  7. 摘抄 Promise原理
  8. iOS之正则表达式的使用
  9. hdu 5402 Travelling Salesman Problem (技巧,未写完)
  10. WAMP(windows+apache+mysql+php)