1 闭包的定义
外部函数中定义一个函数,外部函数返回定义的函数,而不是一个具体的值,这种方式就叫闭包。
计算一个数的 n 次幂,用闭包可以写成下面的代码:
def nth_power(exponent):
def exponent_of(base):
return base ** exponent
return exponent_of # 返回值是exponent_of函数
square = nth_power(2) # 计算一个数的平方
cube = nth_power(3) # 计算一个数的立方
print(square)
# 输出
<function __main__.nth_power.<locals>.exponent(base)>
print(cube)
# 输出
<function __main__.nth_power.<locals>.exponent(base)>
print(square(2)) # 计算2的平方
print(cube(2)) # 计算2的立方
# 输出
4 # 2^2
8 # 2^3
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
这里外部函数 nth_power() 返回值,是函数 exponent_of(),而不是一个具体的数值。需要注意的是,在执行完square = nth_power(2)和cube = nth_power(3)后,外部函数 nth_power() 的参数 exponent,仍然会被内部函数 exponent_of() 记住。这样,之后我们调用 square(2) 或者 cube(2) 时,程序就能顺利地输出结果,而不会报错说参数 exponent 没有定义了。
2 为何使用闭包
上面的代码也可以写成下面的形式而不用闭包
def nth_power_rewrite(base, exponent):
return base ** exponent
- 1
- 2
但使用闭包会让程序变得更简洁易读
# 不适用闭包,每次都需要传入两个参数
res1 = nth_power_rewrite(base1, 2)
res2 = nth_power_rewrite(base2, 2)
res3 = nth_power_rewrite(base3, 2)
# 使用闭包,定义好之后只需要传入一个参数
square = nth_power(2)
res1 = square(base1)
res2 = square(base2)
res3 = square(base3)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
另外,函数开头需要做一些额外工作,而你又需要多次调用这个函数时,将那些额外工作的代码放在外部函数,就可以减少多次调用导致的不必要的开销,提高程序的运行效率。