作为一种编程语言特性,闭包得到了很多编程语言的支持,Python也不例外。所谓闭包,在Python中指的是携带一个或多个自由量的函数。闭包函数的自由量不是函数的参数,而是生成这个函数时的环境变量。一旦闭包生成了,自由变量会绑定在函数上,即使离开创造它的环境,自由量依旧有效。总结一下,闭包的概念有以下三个要点。
- 闭包是一个函数
- 闭包函数是由其他代码生成的
- 闭包函数携带了生成环境的信息
有一个很好的例子可以帮助初学者理解闭包。我们知道,几乎所有的计算模块,比如Python内置的标准数学模块math,提供的对数函数只能计算以2为底、以e为底和以10为底的三种对数。
>>> import math>>> math.log(math.e) # 返回以e为底e的对数
1.0
>>> math.log2(4) # 返回以2为底4的对数
2.0
>>> math.log10(1000) # 返回以10为底1000的对数
3.0
如果想要计算以a为底b的对数,则需要使用对数换底公式。
l o g a b = l o g 10 b l o g 10 a log_ab=\frac{log_{10}b}{log_{10}a} logab=log10alog10b
>>> def glog(b, a): # 返回以a为底b的对数return math.log(b)/math.log(a)
>>> glog(25, 5) # # 返回以5为底25的对数
2.0
我们固然可以像上面的代码那样定义一个函数glog(),计算以任意数为底的对数,但每次总要输入两个参数,和math模块的log()、log2()、log10()函数风格不一致。如果使用闭包,就能生成和math风格一致的对数函数。
>>> def log_factory(n): # 定义一个闭包生成函数def log_n(x): # 生成闭包
return math.log(x)/math.log(n) # 闭包中携带了环境参数n
return log_n # 返回闭包
>>> log5 = log_factory(5) # 用闭包生成器生成闭包
>>> log7 = log_factory(7) # 用闭包生成器生成闭包
>>> log5(25) # 该闭包携带的自由量是5
2.0
>>> log7(49) # 该闭包携带的自由量是7
2.0
以上代码,首先设计了一个对数函数生成器log_factory(),输入一个整数n,就返回一个以n为底的对数函数。继而用这个生成器生成了两个闭包函数,一个名为log5,一个名为log7。最后验证一下,一切都和我们想象的完全一样。