Python中闭包及循环变量的一点注意事项
2017-09-08 本文已影响0人
d773b21d4377
闭包是编程语言通用的一种编程范式,且是面试中必问的问题之一。初学者可能在闭包中纠结好一阵子,当时学习JavaScript时我也在这里踩了不少坑,以Python的闭包为例写点注意事项就当是学习的一点总结吧。
高阶函数除了可以将函数作为参数之外,还可以将函数作为结果值返回,闭包的具体定义可以谷歌一下,通俗点来讲,闭包就是返回函数以及函数的自我调用,我是这么理解的。以如下最精简的函数为例解释闭包:

当我们调用函数f时,返回的并不是阶乘结果,而是返回的g函数体


调用返回结果才会返回阶乘结果


注:不可直接调用函数内部的函数,即g()
我们在函数f内部定义了函数g,内部函数可以引用外部函数f的参数和局部变量,当函数f返回函数g时,相关的参数和局部变量都保存在返回的函数g中,这种就成为闭包。
需要注意的问题是,返回的函数并没有立刻执行,而是直到调用了f()才执行。我们来看一个例子:

可能有人会猜想结果为1,4,9,实际执行打印出来的结果如下

原因就在于返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9。
返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:

这回执行结果符合预期了:
