返回函数
函数可以作为参数,也可以作为返回值。
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum
这样return
过来的sum
是一个函数。要想调用这个函数,需要print(lazy_sum(1,2,3,4,5)())
内部函数sum可以引用外部函数lazy_sum
的参数和局部变量。当外部函数返回内部函数时,相关参数和变量都保存在返回的函数中。这个就叫做闭包。
每次调用外部函数,都会返回一个新的内部函数。
当一个函数返回了一个函数后,其内部的局部变量还被新函数引用。返回的函数类似于惰性序列,用到时才执行。此时引用的值是多少就是多少。
for example
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs
f1, f2, f3 = count()
print(f1(),f2(),f3())
由于返回的内部函数都在引用i
,而调用函数时i代表的值已经是3
了,3
个函数都在引用i
,也就是都是3
。所以结果是9
.
!!!返回函数不要引用任何循环变量,或者后续会发生变化的变量。
如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:
这句话看着啰嗦,其实就是在第一个例子的基础上,把第一个例子当作某个函数的子函数即可。
def count():
def f(j):
def g():
return j*j
return g
fs = []
for i in range(1, 4):
fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
return fs
廖雪峰老师给的注释是,f(i)
立刻被执行,因此i
的当前值被传入f()
。其实意思就是,j
的值对于g()
来说,是一个不变的值,也就是说值被绑定了。跟第一个demo
中传入的args
是一个类型的东西,都是不变的。