既然函数是一个变量,那么当然可以把函数作为结果值返回。先简单看一个示例:
首先我们定义一个函数实现可变参数之积:
>>> from functools import reduce
>>> def fac(*args):
... return reduce(lambda x, y: x * y, args)
...
>>> fac(1, 2, 3, 4, 5)
120
但是,如果不需要立即求得可变参数之积,而是在后面代码中根据需要计算,怎么做? --- 此时可以不返回求积结果,而是返回一个求积函数。
>>> from functools import reduce
>>> def lazy_fac(*args):
... def multiply():
... return reduce(lambda x, y: x * y, args)
... return multiply
...
>>> func = lazy_fac(1, 2, 3, 4, 5, 6, 7)
>>> func
<function lazy_fac.<locals>.multiply at 0x000001E3E8EC47B8>
关于返回函数存在的一个小问题,如下:
def multiply():
m_func = []
for i in range(3):
def mul():
return pow(i, 3)
m_func.append(mul)
return m_func
mul1, mul2, mul3 = multiply()
print(mul1(), mul2(), mul3())
对于上面的代码,我们计划的想要返回0, 1, 8;然而实际却返回了8, 8, 8,为什么?
因为返回的函数引用了变量i,但是调用multiply()返回的每个函数都不是立刻执行,在执行时i已经变为3,所以每个函数都返回了8。因此我们需要注意,返回函数不要引用任何循环变量,或者后续可能会发生改变的变量。如果一定要引用循环变量,则改变如下:
def multiply():
def f(x):
return lambda: pow(x, 3)
m_func = []
for i in range(3):
m_func.append(f(i)) # 由于f(i)是立即执行的,因此当前的i值会被传入,即依次将0, 1, 2传入f(x)中
return m_func
mul1, mul2, mul3 = multiply()
print(mul1(), mul2(), mul3())
示例1:利用闭包返回一个计数器函数,每次调用它返回递增整数:
def createCounter():
# digit = [0]
digit = 0
def counter():
# digit[0] += 1
nonlocal digit
digit += 1
# return digit[0]
return digit
return counter
counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA())
上述代码,注释部分是另一种解决方案。