**函数作为返回值** 在高阶函数那一讲,我们已经知道了,高阶函数可以接受函数作为参数,其实函数也可以作为结果值返回。 在函数嵌套那一讲我们讲了这么一个例子 ~~~ #!/usr/bin/env python3 # -*- coding:utf-8 -*- def myAdd(a,b): '''两数求和悄悄加一''' sum = a + b def innerAdd(num): return num + 1 sum = innerAdd(sum) return sum print(myAdd(1,2)) ~~~ 我们直接把两数求和再加一的结果返回了,如果不需要立刻知道结果,而是在后面的代码中,根据需要再计算怎么办?所以就不能直接返回结果了,而是返回计算的函数。 ~~~ #!/usr/bin/env python3 # -*- coding:utf-8 -*- def myAdd(a,b): '''两数求和悄悄加一''' sum = a + b def innerAdd(): return sum + 1 return innerAdd f = myAdd(1,2) #第一次打印 print(f) #第二次打印 print(f()) #第三次打印 print(myAdd(1,2) == myAdd(1,2)) ~~~ 运行结果 ~~~ airvip@airvip$ ./test.py #第一次打印结果 <function myAdd.<locals>.innerAdd at 0x7f5b2a1ac6a8> #第二次打印结果 4 #第三次打印结果 False ~~~ 当我们调用 myAdd() 时,返回的并不是最终的结果,而是一个函数,再调用函数 f 时,才真正计算得到结果。 需要特别注意第三次打印的结果为 False 假。 在这个例子中,我们在函数 myAdd 中又定义了函数 innerAdd,内部函数 innerAdd 可以使用用外部函数 myAdd 的参数和局部变量,当 myAdd 返回 innerAdd 函数时,其调用的参数和变量都已经保存在返回的函数中,这种方式称为“闭包(Closure)”。 另外当一个函数返回了一个函数后,其内部的局部变量还被新函数使用中,返回的函数并没有立刻执行,只有调用了之后才执行,我们来看下面这个例子。 ~~~ >>> def myAdd(a,b): ... Fl = [] ... sum = a+b ... for i in range(2): ... def innerAdd(): ... return sum + i ... Fl.append(innerAdd) ... return Fl ~~~ 在程序中每次循环都创建了一个新的函数,最后一起把创建的函数都返回了 调用,我们想要的结果是 3,4 ,然而真实结果却是: ~~~ >>> f1,f2 = myAdd(1,2) >>> f1() 4 >>> f2() 4 ~~~ 结果全为 4 ,这是为什么呢?因为返回的函数引用了变量 i,它并没有立刻执行。等到所有函数都返回时,它们使用的变量 i 已经都变成了 1,所以结果就都是 4 了。 那如何解决呢?想办法将传入函数的参数绑定在函数上无法修改,这就需要再创建一个函数。 ~~~ >>> def myAdd(a,b): ... Fl = []; ... sum = a+b ... def center(i): ... def innerAdd(): ... return sum + i ... return innerAdd ... for i in range(2): ... Fl.append(center(i)) ... return Fl ... ~~~ 再次调用 ~~~ >>> f1,f2 = myAdd(1,2) >>> f1() 3 >>> f2() 4 ~~~ 总结: 每次调用以函数作为返回值的函数时,即便传递的参数一模一样,返回的结果也不同。 在编写返回函数时,一定不要使用任何后续操作会发生变化的变量。