走棋子是一个很好的例子理解为什么用闭包。
资料来自网易云课堂
假设需求是给定一颗在[0,0]位置的棋子,用户交互输入移动方向与步数,写一个函数记录棋子的位置变化。
这个函数可以是这样的:以用户输入的方向与步数变量为参数,计算出移动后的位置值作为函数返回值。那么走第一步时,基于初始位置值[0,0]做计算,返回新的位置值[a,b]。第二步呢?计算第二步走完之后的位置值需要基于[a,b]而不是[0,0]。也就是说,函数每调用一次,它的返回值都要保存下来作为下一次调用的参数。当然全局变量可以做到,但不是一个好选择。
采用闭包函数是这样的:
参考了云课堂‘用python做些事’这门课程。
origin = [0, 0] # 坐标系统原点 legal_x = [0, 50] # x轴方向的合法坐标 legal_y = [0, 50] # y轴方向的合法坐标
def create(pos): def player(direction,step): # 这里应该首先判断参数direction,step的合法性,比如direction不能斜着走,step不能为负等 # 然后还要对新生成的x,y坐标的合法性进行判断处理 new_x = pos[0] + direction[0]*step new_y = pos[1] + direction[1]*step pos[0] = new_x pos[1] = new_y #注意!此处不能写成 pos = [new_x, new_y],原因在上文有说过 return pos return player
player1 = create(origin[:]) # 创建棋子player1,起点为原点 print player1([1,0],10) # 向x轴正方向移动10步 print player1([0,1],20) # 向y轴正方向移动20步 print player1([-1,0],10) # 向x轴负方向移动10步 |
这个例子帮助我理解了闭包及其用处。
另外参考文章http://www.2cto.com/kf/201503/386253.html
其中两点助于理解:
1. 内部嵌套的函数称为闭包,它可以访问不在自己作用域的变量,即外部函数的变量。
2. 闭包会保留来自外围作用域变量的信息。