埃尔法哥哥:Python——五分钟理解函数式编程与闭包( 三 )
闭包有一个很大的问题就是不能使用循环变量 , 这个坑藏得很深 , 因为单纯从代码的逻辑上来看是发现不了的 。 也就是说逻辑上没问题的代码 , 运行的时候往往会出乎我们的意料 , 这需要我们对底层的原理有深刻地了解才能发现 , 比如我们来看一个例子:
文章图片
在上面这个例子当中 , 我们使用了for循环来创建了3个闭包 , 我们使用fs存储这三个闭包并进行返回 。 然后我们通过调用test , 来获得了这3个闭包 , 然后我们进行了调用 。
这个逻辑看起来应该没有问题 , 按照道理 , 这3个闭包是通过for循环创建的 , 并且在闭包当中我们用到了循环变量i 。 那按照我们的想法 , 最终输出的结果应该是[3,4,5] , 但是很遗憾 , 最后我们得到的结果是[5,5,5] 。
看起来很奇怪吧 , 其实一点也不奇怪 , 因为循环变量i并不是在创建闭包的时候就set好的 。 而是当我们执行闭包的时候 , 我们再去寻找这个i对应的取值 , 显然当我们运行闭包的时候 , 循环已经执行完了 , 此时的i停在了2 。 所以这3个闭包的执行结果都是2+3也就是5 。 这个坑是由Python解释器当中对于闭包执行的逻辑导致的 , 我们编写的逻辑是对的 , 但是它并不按照我们的逻辑来 , 所以这一点要千万注意 , 如果忘记了 , 想要通过debug查找出来会很难 。
总结
虽然从表面上闭包存在一些问题和坑点 , 但是它依然是我们经常使用的Python高级特性 , 并且它也是很多其他高级用法的基础 。 所以我们理解和学会闭包是非常有必要的 , 千万不能因噎废食 。
其实并不只是闭包 , 很多高度抽象的特性都或多或少的有这样的问题 。 因为当我们进行抽象的时候 , 我们固然简化了代码 , 增加了灵活度 , 但与此同时我们也让学习曲线变得陡峭 , 带来了更多我们需要理解和记住的内容 。 本质上这也是一个trade-off , 好用的特性需要付出代码 , 易学易用的往往意味着比较死板不够灵活 。 对于这个问题 , 我们需要保持心态 , 不过好在初看时也许有些难以理解 , 但总体来说闭包还是比较简单的 , 我相信对你们来说一定不成问题 。
推荐阅读
- 三生石哥哥多家快递公司宣布会提高快递运送费用
- 埃尔法哥哥互联网空间会被用完吗?2025年全世界数据总量将会超过16万EB
- 埃尔法哥哥 人工智能与科技传播领域的融合
- 【埃尔法哥哥】kNN分类算法及其python实现
- 埃尔法哥哥■区块链技术迎风而上,ETX公链解决行业痛点,信息时代安全为王
- 埃尔法哥哥@Spark 数据倾斜的 8 大实用方法,解决
- 『埃尔法哥哥』为什么你写的代码别人看不懂?
- 「埃尔法哥哥」ICCV2019:DeepFill一个用于生成图像修复任务的开源框架
- 『埃尔法哥哥』每一个程序员的必经之事
- 埃尔法哥哥■假装网络工程师-TCP/IP与静态路由