前两天写了一篇文章,讲了一下Python的闭包。刚好今天又看到一个小问题,和Python闭包有点相关。顺手记录下来。
如下一段代码,
funcs = []
for i in xrange(10):
def bar(n):
return n + i
funcs.append(bar)
print funcs[3](5)
这段代码中,我们期望得到的结果是3+5为8。但是实际得到的结果是什么呢?是14。
14是怎么来的?
反汇编看看:
7 0 LOAD_FAST 0 (n)
3 LOAD_GLOBAL 0 (i)
6 BINARY_ADD
7 RETURN_VALUE
注意i是global。
得到14的原因就是,funcs[3]这个函数对象获取i的值,是在执行的时候。而i的作用域是global。也就是说,当这个func开始执行的时候,i已经变成9了。那么结果当然等于14了。
从这个结果看,以上代码和下面代码效果是等价的。
funcs = []
for i in xrange(10):
pass
def bar(n):
return n + i
funcs.append(bar)#这句重复10遍
print funcs[3](5)
很无趣吧。那么考虑一下,如果把i丢到闭包来做会怎样?
funcs = []
def foo(m):
for i in xrange(m):
def bar(n):
return n + i
funcs.append(bar)
foo(10)
print funcs[3](5)
很遗憾,结果依然是14.
反汇编代码如下:
9 0 LOAD_FAST 0 (n)
3 LOAD_DEREF 0 (i)
6 BINARY_ADD
7 RETURN_VALUE
唉,只是傻傻的远程访问而已。
“所有的bar代码中,i仅仅只是在closure中的一个引用而已。指向的依然是同一个对象。当这个对象被改变,所有的bar执行的时候获得的值都是修改后的值”。
顺手写了一段JavaScript来测试,发现结果是一样的。也是会全局改变。具体代码如下:
但是用haskell实现了一个,完全符合预期的结果。
main = do
let funcs = [(\n -> n + i) | i <- [1..10] ]
let x : xs = funcs
return (x 4)
返回结果是5。
看来Python对FP的支持还是比不上Haskell这种正统的函数式语言。
个人觉得如果Python要发展FP的话,可以考虑如下解决方案:区别本地变量和闭包变量。当声明函数的时候将闭包变量拷贝一份到本地,同时保留指向原闭包对象的引用。在搜索名字的时候,始终都是先搜索本地变量,再搜索本地闭包变量副本,再搜索全局变量。当需要修改的时候,如果是本地变量就直接修改。如果是闭包变量的时候,将原来闭包真正指向的对象进行修改,同时覆盖掉本地的闭包副本。
这个方法只是暂时的考虑,没有仔细的推敲。乍看之下似乎可以解决问题。
不过,Python毕竟是OO的语言。没有Haskell或者Lisp那种天生的作用域的控制能力。唉。那就用OO的方式来搞Python把。
分享到:
相关推荐
二元关系的闭包运算则是研究这些关系性质的重要工具。本主题将深入探讨二元关系闭包运算的理论、计算方法以及如何通过编程实现可视化。 首先,我们需要理解什么是二元关系。在集合A上,一个二元关系R是A的子集,...
`function`和`module`对象的内部结构在SmallPython中有详细呈现,包括函数的闭包、装饰器的实现以及模块的导入机制。 五、异常处理与错误报告 Python的异常处理机制使得程序能够优雅地处理错误。在SmallPython中,...
6. **函数式编程**:Python支持函数式编程概念,如高阶函数、闭包、装饰器和生成器。这些工具使代码更简洁、可读性更强。 7. **迭代器和生成器**:Python的迭代器协议允许对象以迭代方式访问。生成器是轻量级的迭代...
Python是一种高级编程语言,以其简洁明了的语法和...配合实际的编程练习,你将能够运用Python解决各种实际问题,无论是在学术研究、数据分析还是软件开发领域。所以,准备好你的编辑器,让我们一起探索Python的世界吧!
通过《Python Handbook》这本电子书,读者将全面地学习Python编程,无论是在学术研究、数据科学,还是Web开发等领域,都能找到实用的指导和参考资料。同时,不断实践和应用所学知识,将有助于成为一位熟练的Python...
8. **函数式编程元素**:Python支持高阶函数、闭包和列表推导等函数式编程特性。C语言源码将揭示这些特性的实现细节。 9. **线程和并发**:Python-2.0.1的源码还包含了对多线程的支持,尽管Python的全局解释器锁...
**Python简介** Python是一种高级编程语言,以其...通过系统学习并实践,你将能够熟练掌握Python,为从事机器学习、深度学习等领域的研究打下坚实基础。记得理论结合实践,不断探索和尝试,才能更好地提升编程技能。
书中涵盖了一系列重要的主题,包括但不限于安装过程、编写第一个Python程序、内置数据类型的理解和运用、字符串操作、正则表达式的使用、闭包与生成器的概念、面向对象编程的基础以及高级迭代器等。此外,还介绍了...
7. **函数式编程**:可能涉及高阶函数、闭包、装饰器等概念,展示Python在函数式编程风格上的特点。 8. **正则表达式**:教授如何使用Python的re模块进行文本匹配和搜索,进行数据清洗和预处理。 9. **网络编程**...
这一过程涉及到了许多Python的核心概念,如作用域规则、闭包、生成器、装饰器等,这些都会通过源码解析的方式进行深入探讨。 此外,Python的类型系统是另一个重要的研究方向。Python是动态类型语言,这意味着变量在...
6. **函数式编程**:探讨Python中的高阶函数,如map、filter和reduce,以及lambda表达式和闭包等概念。 7. **Web开发**:如果面向项目,可能会涉及到Django或Flask等Python Web框架的基础知识,如路由、模板渲染、...
通过深入阅读和研究"py_s.chm",开发者不仅可以掌握Python的基本语法,还能深入理解Python的运行机制,这对于成为一名资深Python开发者至关重要。同时,这个资源也可能包含一些调试技巧、扩展开发以及对Python源码的...
5. **作用域和命名空间**:Python的局部作用域、全局作用域以及闭包是如何工作的?源码中`PyObject *locals, *globals`的使用解释了这些概念。 6. **异常处理**:Python的异常处理基于try/except/finally结构,源码...
6. **函数式编程**:Python支持函数式编程风格,如高阶函数、闭包、生成器等,可能会在某些题目中体现。 7. **文件操作**:读写文件、处理日志等实际操作,考察对Python I/O的理解。 8. **网络编程**:Python提供...
7. **生成器与协程**:深入研究Python的生成器(generator)和协程(coroutine),它们在异步编程中的应用,以及如何通过yield关键字实现控制流。 8. **类与继承**:详细剖析Python的面向对象特性,如类的定义、...
通过研究这些官方文档,开发者不仅可以学习Python 2.7的基本语法和高级特性,还可以深入了解如何编写高效、可维护的Python代码,同时为向Python 3的迁移做好准备。因此,对于任何想在Python 2.7环境下工作的开发者来...
总之,《计算机程序的构造与解释》(SICP)是一本值得深入研究的著作,它通过Lisp和Python等语言,向我们展示了计算世界的广阔与深邃。无论你是初学者还是经验丰富的程序员,这本书都能为你提供新的视角和思考方式。...
作为Python学习资料,它适合初学者入门,也适合有经验的开发者深入研究。 在Python的世界里,语法简洁明了,易于上手,但其强大的功能和广泛的应用领域使其成为现代编程语言中的翘楚。Python支持多种编程范式,包括...
1. **函数式编程**:Python支持函数式编程范式,包括高阶函数、闭包、装饰器和生成器。高阶函数是可以接受函数作为参数或返回函数的函数,例如`map()`和`filter()`。闭包是拥有自由变量的函数,即使在外部作用域已经...