前言
「刻意练习」中将行动者分为四阶,以10为底,N为幂,代表能够持续行动的天数。
按照这个标准,一阶行动者一般做一件事在10的量级,二阶行动者成功的完成了10的2次方,三阶行动者则表示把一件事情持续行动到10的3次方,四阶行动者 ,就过于宏大,往往就是几代人持续地完成,持续的执行某件事,也就是我们说的家族传承。
今天是连续写作的第十天,之前都是断断续续的写作,都说10天左右就面临极大的放弃风险,或者直接放弃,这也是一阶行动者的瓶颈,我不想一直做一个总是在入门口徘徊的loser,我想做一个不断进阶的行动者,写下这段文字,是希望大家互相监督,等自己成功进阶到二阶,咱们再一起把酒言欢。
废话少絮,直接进入今天的内容。
正文
通过前面的学习,知道了什么是闭包?闭包有什么作用?以及闭包的意义?那今天我想通过一个实例说明闭包并不是必不可少的东西。
假设有一个旅行者,去某地旅游,每走一步打印一个值,旅行者处的位置是在前一次位置的基础上进行叠加更新。
首先,用非闭包的方法,题目并不难,大家很容易想到编一个函数实现这个功能,没错,我编写的代码如下
origin = 0
def go(step):
new_pos = origin +step
origin = new_pos
return new_pos
print(go(2))
print(go(3))
print(go(6))
但是,结果却不能运行,为什么呢?
UnboundLocalError: local variable 'origin' referenced before assignment
通过观察代码,可以看到origin这个全局变量,在函数内部还有一个origin,但两个表示的意义不同,也就是说没有将在函数外面的origin变量当做是全局变量在函数中使用,怎么解决呢?
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))
可以看到打印的结果和我们预想的是一样的。
2
5
11
然后再用闭包的方法实现这个例子,编写的代码如下
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这个命令,闭包中有强制声明变量不是局部变量的命令,如下
nonlocal pos
此外,把每一次位置更新时的环境变量用.__closure__属性打印出来,可以更加清楚的知道闭包的环境变量起到保存现场,记忆了上次调用状态的作用。
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)
2
2
5
5
11
11
关于闭包这部分内容就说完了,明天开始学习函数式编程。大家学习知识还是要有耐心,不要觉得这些例子都很简单,但是复杂不就是由简单演变而来的吗?
总结
分享一个学习Python的方法,首先就是要对知识理解入脑,尽最大可能理解知识的架构组成;
其次还要对知识复盘,我们在看视频、看文档学习知识时,往往跟别人思路走下来,感觉很流畅,然后自己觉得这部分内容没问题了,但等到实际运用时却两眼一抹黑;
最后就是还原知识,通过复盘我们可以知道哪些敌方掌握的还不熟练,再进行巩固,最后抛开所有视频书籍,按自己的思路对所学知识进行还原重构。
如果能严格执行上面的三部曲,肯定能奏出华丽的人生篇章。