闭包简介
闭包其实和嵌套函数类似,不同的是,闭包的外部函数返回的是一个函数,而不是一个具体的值。返回的函数通常赋于一个变量,这个变量可以在后面被继续执行调用。
def nth_power(exponent):
def exponent_of(base):
return base ** exponent
return exponent_of # 返回值是exponent_of函数
square = nth_power(2) # 计算一个数的平方
cube = nth_power(3) # 计算一个数的立方
square
# 输出
<function __main__.nth_power.<locals>.exponent(base)>
cube
# 输出
<function __main__.nth_power.<locals>.exponent(base)>
print(square(2)) # 计算2的平方
print(cube(2)) # 计算2的立方
# 输出
4 # 2^2
8 # 2^3
这里外部函数nth_power()返回值,是函数exponent_of(),而不是一个具体的数值。需要注意的是,在执行完square = nth_power(2)和cube = nth_power(3)后,外部函数nth_power()的参数exponent,仍然会被内部函数exponent_of()记住。这样,之后我们调用square(2)或者cube(2)时,程序就能顺利地输出结果,而不会报错说参数exponent没有定义了。
使用闭包的优点
为什么要闭包呢?上面的程序,我也可以写成下面的形式:
def nth_power(base, exponent):
return base ** exponent
优点一:简洁易读
设想一下,比如你需要计算很多个数的平方,闭包的写法能让每次调用函数都可以少输入一个参数,表达更为简洁:
# 不使用闭包
res1 = nth_power(base1, 2)
res2 = nth_power(base2, 2)
res3 = nth_power(base3, 2)
...
# 使用闭包
square = nth_power(2)
res1 = square(base1)
res2 = square(base2)
res3 = square(base3)
优点二:降低开销
如果在函数开头需要做一些额外工作(比如对入参进行有效性校验,或者是与数据库建立连接等等),而你又需要多次调用这个函数时,将那些额外工作的代码放在外部函数,就可以减少多次调用导致的不必要的开销,提高程序的运行效率。
优点三:可以与装饰器配合使用
待补充。。。