Chinaunix首页 | 论坛 | 博客
  • 博客访问: 43664
  • 博文数量: 15
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 176
  • 用 户 组: 普通用户
  • 注册时间: 2014-01-31 01:57
个人简介

资深码农

文章分类

全部博文(15)

文章存档

2016年(3)

2014年(12)

我的朋友

分类: Python/Ruby

2016-09-17 11:20:18

提到Closure(闭包),大家会联想到JavaScript,但实际上Python也是支持它的,尽管不十分常见,但是Closure的确也是Python一个十分重要的组成。Closure,或者说factory function,本质上来说是一段作用域,在这个作用域中保存着其中的变量的状态。看下面一段代码

点击(此处)折叠或打开

  1. def func(x):
  2.     action = (lambda n: x ** n)
  3.     return action

  4. action = func(3)

我们首先定义额一个函数func,在其中定义一个变量action,其值是一个lambda表达式(匿名函数) x ** n,也就是x的n次方,然后返回action。接下来把func(3)赋值给action,那么现在action等于什么呢?答案是3 ** n,因此如下语句将返回9。

点击(此处)折叠或打开

  1. action(2)
如果是C/C++的程序员看到这会很疑惑,一个函数结束调用以后,其中的变量就应该被回收掉了,可是这里很明显func(3)结束调用以后其内部的x值一直都保留为3,这到底是为什么呢?因为Python中的函数其实就是一个对象,def的作用不过是创建一个对象然后赋给这个函数名而已。
不过在Closure的使用上一不小心就会犯错,看下面这个例子,

点击(此处)折叠或打开

  1. def makeActions():
  2.     acts = []
  3.     for i in range(5):
  4.     acts.append(lambda x: i ** x)
  5.     return acts
  6. acts = makeActions()
这段代码师徒在makeActions的函数中返回一个acts,这个acts是一个长度是5的数组,数组的每一个元素是一个匿名函数表达式,即从0至4的x次幂。可是结果却出人意料,实际上不论acts[0](2)还是acts[4](2)都返回16,即4的平方。出现这种情况的原因是:Closure内部的变量的值只有在内部定义的函数也就是acts被调用的时候才会被确定,因此不论acts[0]还是acts[4]他们内部的i值都是循环结束时的值4。
要解决这个问题,我们需要利用函数的默认参数来显示的把内部参数的值固定,原因是默认参数的值是在函数创建的那一刻确定的,

点击(此处)折叠或打开

  1. def makeActions():
  2.     acts = []
  3.     for i in range(5):
  4.     acts.append(lambda x, i=i: i ** x)
  5.     return acts
  6. acts = makeActions()
这样acts[0](2)就是0,act[4](2)的值就是16了。



阅读(1566) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~