python闭包

周围有些同事初学python,往往对python的一些高级特性,比如生成器(Generator), 闭包(closure),装饰器(Decorator)感到有点不太容易理解,虽然这些特性并非python独有,但真的掌握了一定会让你感觉原来生活如此美好。

闭包介绍

闭包概念:在一个内部函数中,对外部作用域的变量进行引用,(并且一般外部函数的返回值为内部函数),那么内部函数就被认为是闭包。举个栗子先:
在这里插入图片描述

在函数startAt中定义了一个incrementBy函数,incrementBy访问了外部函数startAt的变量,并且函数返回值为incrementBy函数(注意python是可以返回一个函数的,这也是python的特性之一)
在这里插入图片描述

上面代码中a其实就是一个函数,上面代码执行的结果:
在这里插入图片描述

从结果我们不难看出,a是函数incrementBy而不是startAt这个有点绕,但是并不难理解,因为return回来的是incrementBy函数。
在这里插入图片描述

输出是:
在这里插入图片描述

如果调用函数a的话,得到的结果是传入参数的整数值加。

常见错误

闭包无法修改外部函数的局部变量。这个是什么意思呢?
在这里插入图片描述

如果innerFunc可以修改x的值的话,x的值前后会发生变化,但结果是:
在这里插入图片描述

在innerFunc中x的值发生了改变,但是在outerFunc中x的值并未发生变化。
python循环中不包含域的概念。

按照大家正常的理解,应该输出的是0, 2, 4对吧?但实际输出的结果是:4, 4, 4. 原因是什么呢?loop在python中是没有域的概念的,flist在像列表中添加func的时候,并没有保存i的值,而是当执行f(2)的时候才去取,这时候循环已经结束,i的值是2,所以结果都是4。
在这里插入图片描述

其实修改方案也挺简单的:

在这里插入图片描述

在func外面再定义一个makefunc函数,func形成闭包,结果就正确了。

闭包的作用

闭包可以保存当前的运行环境,以一个类似棋盘游戏的例子来说明。假设棋盘大小为50*50,左上角为坐标系原点(0,0),我需要一个函数,接收2个参数,分别为方向(direction),步长(step),该函数控制棋子的运动。 这里需要说明的是,每次运动的起点都是上次运动结束的终点。

参考代码:
在这里插入图片描述

结果是
在这里插入图片描述

也就是我们先沿X轴前进了10,然后沿Y轴前进了20,然后反方向沿X轴退了10,坐标分别问[10,0], [10, 20], [0, 20]。
当然,闭包在爬虫以及web应用中都有很广泛的应用,并且闭包也是装饰器的基础,这些内容笔者会在后续的文章中分别介绍,这里就不多谈了。理解了本文中的概念,你应该知道的关于闭包的知识也差不多了,请在自己的编程中尽情使用吧。

参考连接:

Closure (computer programming)
About python closure
[]Python中的闭包实例详解_python_脚本之家(https://www.jb51.net/article/54498.htm)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值