前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >漫谈闭包

漫谈闭包

作者头像
stormwen
发布2019-08-05 11:17:33
3530
发布2019-08-05 11:17:33
举报
文章被收录于专栏:公众号:googpy公众号:googpy

前言

「刻意练习」中将行动者分为四阶,以10为底,N为幂,代表能够持续行动的天数。

按照这个标准,一阶行动者一般做一件事在10的量级,二阶行动者成功的完成了10的2次方,三阶行动者则表示把一件事情持续行动到10的3次方,四阶行动者 ,就过于宏大,往往就是几代人持续地完成,持续的执行某件事,也就是我们说的家族传承。

今天是连续写作的第十天,之前都是断断续续的写作,都说10天左右就面临极大的放弃风险,或者直接放弃,这也是一阶行动者的瓶颈,我不想一直做一个总是在入门口徘徊的loser,我想做一个不断进阶的行动者,写下这段文字,是希望大家互相监督,等自己成功进阶到二阶,咱们再一起把酒言欢。

废话少絮,直接进入今天的内容。

正文

通过前面的学习,知道了什么是闭包?闭包有什么作用?以及闭包的意义?那今天我想通过一个实例说明闭包并不是必不可少的东西。

假设有一个旅行者,去某地旅游,每走一步打印一个值,旅行者处的位置是在前一次位置的基础上进行叠加更新。

首先,用非闭包的方法,题目并不难,大家很容易想到编一个函数实现这个功能,没错,我编写的代码如下

代码语言:javascript
复制
origin = 0

def go(step):
    new_pos = origin +step
    origin = new_pos
    return new_pos


print(go(2))
print(go(3))
print(go(6))

但是,结果却不能运行,为什么呢?

代码语言:javascript
复制
UnboundLocalError: local variable 'origin' referenced before assignment

通过观察代码,可以看到origin这个全局变量,在函数内部还有一个origin,但两个表示的意义不同,也就是说没有将在函数外面的origin变量当做是全局变量在函数中使用,怎么解决呢?

代码语言:javascript
复制
origin = 0

def go(step):
    global origin
    new_pos = origin +step
    origin = new_pos
    return new_pos


print(go(2))
print(go(3))
print(go(6))

可以看到打印的结果和我们预想的是一样的。

代码语言:javascript
复制
2
5
11

然后再用闭包的方法实现这个例子,编写的代码如下

代码语言:javascript
复制
origin = 0

def factory(pos):
    def go(step):
        new_pos = pos + step
        pos = new_pos
        return new_pos
    return go

tourist = factory(origin)
print(tourist(2))

运行代码还会出现错误,原因和用函数方法是一样的,这里肯定不能用global这个命令,闭包中有强制声明变量不是局部变量的命令,如下

代码语言:javascript
复制
nonlocal pos

此外,把每一次位置更新时的环境变量用.__closure__属性打印出来,可以更加清楚的知道闭包的环境变量起到保存现场,记忆了上次调用状态的作用。

代码语言:javascript
复制
origin = 0

def factory(pos):
    def go(step):
        nonlocal pos   #强制声明不是局部变量
        new_pos = pos + step
        pos = new_pos
        return new_pos
    return go

tourist = factory(origin)
print(tourist(2))
print(tourist.__closure__[0].cell_contents)
print(tourist(3))
print(tourist.__closure__[0].cell_contents)
print(tourist(6))
print(tourist.__closure__[0].cell_contents)
代码语言:javascript
复制
2
2
5
5
11
11

关于闭包这部分内容就说完了,明天开始学习函数式编程。大家学习知识还是要有耐心,不要觉得这些例子都很简单,但是复杂不就是由简单演变而来的吗?

总结

分享一个学习Python的方法,首先就是要对知识理解入脑,尽最大可能理解知识的架构组成;

其次还要对知识复盘,我们在看视频、看文档学习知识时,往往跟别人思路走下来,感觉很流畅,然后自己觉得这部分内容没问题了,但等到实际运用时却两眼一抹黑;

最后就是还原知识,通过复盘我们可以知道哪些敌方掌握的还不熟练,再进行巩固,最后抛开所有视频书籍,按自己的思路对所学知识进行还原重构。

如果能严格执行上面的三部曲,肯定能奏出华丽的人生篇章。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 googpy 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档