python面试中面试官问你什么是闭包(closure)?该如何回答?
前言
本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理。
PS:如有需要Python学习资料的小伙伴可以点击下方链接自行获取
闭包和装饰器有什么区别呢?
闭包传递的是变量,而装饰器传递的是函数对象,只是传的参数内容不一样,闭包的概念包含了装饰器,可以说装饰器是闭包的一种,它只是传递函数对象的闭包。
先看一个面试题
先看一个经典的面试题,很有代表性, 运行以下代码会输出什么呢?为什么会是这种结果?
运行结果
运行的结果是4个6 ,并不是我们想的 :0, 2, 4, 6。上面的代码用到了列表推导式,还有个匿名函数lambda,直接去阅读不太好理解,可以把匿名函数转成自己定义一个函数。
于是上面的代码等价于:
为了更好的理解,可以先去掉外面的一层fun()
这里只定义了一个函数 inner(), 有 2 个变量,i 是函数外部的变量,x 是函数内部的变量。
现在问题的关键在理解函数外部变量和函数内部变量的区别了, 接下来再看一个简单的例子
运行结果:101 103 103
也就是函数外部变量a是可变的,后面给a重新赋值了,会替换前面的值。上面的 inner(x) 函数也是一样,外部变量 i 的值是0, 1, 2, 3变化,最后的3 会覆盖前面的值,所以得到的结果都是6
如何解决上面的问题,接下来就是要说的闭包的概念了!
什么是闭包?
闭包就是外部函数中定义了一个内部函数,当外部函数返回内部函数对象(注意是函数对象)时,程序接收了内部函数的定义(此时并未被执行),当再次执行这个返回值时,这个被返回的函数才能被执行。
创建一个闭包必须满足以下几点:
- 必须有一个内嵌函数
- 内嵌函数必须引用外部函数中的变量
- 外部函数的返回值必须是内嵌函数
闭包和装饰器的区别:闭包传递的是变量,而装饰器传递的是函数,除此之外没有任何区别,或者说装饰器是闭包的一种,它只是传递函数的闭包。
以下是闭包的一个标准示例:
上面的问题,用闭包来解决
运行结果
使用列表推导式
这样就可以得到我们的预期结果:0 2 4 6
通过上面的案例就可以了解到闭包的作用了,它保存了函数的外部变量,不会随着变量的改变而改变了。