原因是闭包(lambdas或其他)关闭名称,而不是值。定义lambda x: test_fun(n, x)时,不会计算n,因为它在函数内部。当函数被称为时计算,此时存在的值是循环的最后一个值。

一开始你说你想“使用闭包从函数签名中删除一个变量”,但实际上并不是这样。(不过,请参阅下面的内容,以获得可能满足您的方法,具体取决于您所说的“消除”是什么意思。)定义函数时,不会计算函数体中的变量。为了让函数获取在函数定义时存在的变量的“快照”,必须将变量作为参数传递。通常的方法是给函数一个参数,其默认值是来自外部作用域的变量。看看这两个例子之间的区别:>>> stuff = [lambda x: n+x for n in [1, 2, 3]]

>>> for f in stuff:

... print f(1)

4

4

4

>>> stuff = [lambda x, n=n: n+x for n in [1, 2, 3]]

>>> for f in stuff:

... print f(1)

2

3

4

在第二个示例中,将n作为参数传递给函数“locks-In”该函数的当前值n。如果你想用这种方式锁定值,就必须这样做。(如果不是这样的话,全局变量之类的东西根本就不起作用;在使用时必须查找自由变量。)

请注意,此行为的任何内容都不是lambdas特有的。如果使用def定义引用封闭作用域中的变量的函数,则相同的作用域规则有效。

如果您真的想这样做,可以避免向返回的函数中添加额外的参数,但要这样做,必须将该函数包装到另一个函数中,如:>>> def makeFunc(n):

... return lambda x: x+n

>>> stuff = [makeFunc(n) for n in [1, 2, 3]]

>>> for f in stuff:

... print f(1)

2

3

4

在这里,内部lambda在调用时仍会查找n的值。但是它引用的n不再是全局变量,而是封闭函数makeFunc中的局部变量。每次调用makeFunc时都会创建此局部变量的新值,返回的lambda会创建一个闭包,该闭包“保存”对调用makeFunc有效的局部变量值。因此,在循环中创建的每个函数都有自己的“private”变量,名为x。(对于这种简单的情况,也可以使用lambda作为外部函数---stuff = [(lambda n: lambda x: x+n)(n) for n in [1, 2, 3]]--但这不太可读。)

注意,您仍然需要将n作为参数传递,只是这样做,您不会将其作为参数传递给最终进入stuff列表的同一个函数;而是将其作为参数传递给创建要放入stuff的函数的助手函数。使用这两个函数方法的优点是,返回的函数是“干净的”,并且没有额外的参数;如果包装接受许多参数的函数,这可能很有用,在这种情况下,记住参数在列表中的位置可能会变得混乱。缺点是,这样做,生成函数的过程会更复杂,因为您需要另一个封闭函数。

结果是有一个折衷方案:您可以使函数创建过程更简单(即,不需要两个嵌套函数),但是您必须使结果函数更复杂(即,它有这个额外的n=n参数)。或者可以使函数更简单(即,它没有n=n参数),但是必须使函数创建过程更复杂(即,需要两个嵌套函数来实现机制)。

python 闭包 lambda_Python lambda闭包范围相关推荐

  1. Python基础(六)—函数式编程(内部函数、闭包、lambda、filter/map/reduce/sorce、偏函数)

    内部函数 Python中函数的作用域由def关键字界定,函数内的代码访问变量的方式是从其所在层级由内向外,若往外直至全局作用域都查找不到的话代码会抛异常. 主要看以下代码的差别~~ "&qu ...

  2. 如何设计一门语言(七)——闭包、lambda和interface

    人们都很喜欢讨论闭包这个概念.其实这个概念对于写代码来讲一点用都没有,写代码只需要掌握好lambda表达式和class+interface的语义就行了.基本上只有在写编译器和虚拟机的时候才需要管什么是 ...

  3. python教程闭包_Python教程 闭包的特性

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...

  4. python函数作用域与闭包_python基础-08-内置函数、作用域、闭包、递归

    python基础-内置函数.作用域.闭包.递归 1.常见的内置函数 常见的内置函数: 查看内置函数: print(dir(__builtins__)) 常见函数 type() 数据类型 print() ...

  5. 一篇文章解决Python函数式编程与闭包的问题

    函数式编程 函数式编程这个概念我们可能或多或少都听说过,刚听说的时候不明觉厉,觉得这是一个非常黑科技的概念.但是实际上它的含义很朴实,但是延伸出来许多丰富的用法. 在早期编程语言还不是很多的时候,我们 ...

  6. 三分钟理解Python函数式编程与闭包

    函数式编程 函数式编程这个概念我们可能或多或少都听说过,刚听说的时候不明觉厉,觉得这是一个非常黑科技的概念.但是实际上它的含义很朴实,但是延伸出来许多丰富的用法. 在早期编程语言还不是很多的时候,我们 ...

  7. python装饰器与闭包_Python 装饰器和闭包

    Python 装饰器和闭包 装饰器是 Python 中常见的语法糖,这篇文章讲了闭包和装饰器的原理,并且分析了函数中变量的作用域,以及尝试总结了常见的坑. 装饰器基础 首先来看看装饰器的定义:装饰器本 ...

  8. python高阶函数闭包装饰器_5.初识python装饰器 高阶函数+闭包+函数嵌套=装饰器...

    一.什么是装饰器? 实际上装饰器就是个函数,这个函数可以为其他函数提供附加的功能. 装饰器在给其他函数添加功能时,不会修改原函数的源代码,不会修改原函数的调用方式. 高阶函数+函数嵌套+闭包 = 装饰 ...

  9. java闭包和lambda关系_Lambda表达式和闭包Closure

    简介 我们通常讲到闭包,一般都是指在javascript的环境中.闭包是JS中一个非常重要的也非常常用的概念.闭包产生的原因就是变量的作用域范围不同.一般来说函数内部的定义的变量只有函数内部可见.如果 ...

最新文章

  1. Web应用中的缓存一致性问题
  2. 双亲委派机制 详解(手画详图)面试高频 你值得拥有!!!
  3. 两个操作字符串的方法:读取指定位置的字符和找出某个字符串的位置
  4. Linux—JVM等性能调优监控
  5. 第一款Layer 2钱包Rollups Wallet已上线苹果AppStore
  6. 【论文解读】图文并茂带你细致了解ELMo的各种细节
  7. 最简单爬虫rvest_告别复制粘贴
  8. SQLite:在Julia中判断一个表是否存在数据库中?
  9. 概率论与数理统计加法公式
  10. LeetCode||颜色分类--给定一个包含红色、白色和蓝色,一共 *n* 个元素的数组,**原地**对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
  11. Android TextView设置跑马灯效果
  12. 4.8 单元格背景样式的设置 [原创Excel教程]
  13. 如何绘制业务流程图?
  14. 手机快速将语音转换成文字的方法!详细步骤教你使用,方便又高效
  15. (实测可用)STM32CubeMX教程-STM32L431RCT6开发板研究串口通信(SPI flash)
  16. 元旦经典文案素材赏析
  17. 【历史上的今天】3 月 14 日:微软发布 IE9;黑莓创始人出生;圆周率计算创造新纪录
  18. 传感器选型(sensor)
  19. 国内外的几十个测试学习网站
  20. 大学毕业论文写作技巧干货(毕业论文写作中的Word实用技巧)

热门文章

  1. tree | 分类回归树模型
  2. 凸包Graham算法
  3. 黑杰克blackjack 游戏的简化版(第一个游戏程序)
  4. 基本回路系统和基本割集系统
  5. 已知网络号如何求子网掩码?
  6. python_docx读取word的内容
  7. [ZT]一个三十岁男人的婚姻思考(三)
  8. 田野调查手记·浮山摩崖石刻(五)
  9. JavaScript面向对象学习深拷贝、浅拷贝(三)
  10. 【图像识别】基于模板匹配算法求解车牌识别问题matlab代码含GUI界面