一、返回函数
Python的函数不但可以返回int、str、list、dict等数据类型,还可以返回函数!
例如,定义一个函数 f(),我们让它返回一个函数 g,可以这样写:
def f(): print 'call f()...' # 定义函数g: def g(): print 'call g()...' # 返回函数g: return g 复制代码
仔细观察上面的函数定义,我们在函数 f内部又定义了一个函数 g。由于函数 g也是一个对象,函数名 g就是指向函数 g的变量,所以,最外层函数 f可以返回变量 g,也就是函数 g本身。
调用函数 f,我们会得到 f返回的一个函数:
>>> x = f() #调用f()
call f()...
>>> x #变量x是f()返回的函数:
<function g at 0x1037bf320> 复制代码
>>> x() # x指向函数,因此可以调用
call g()... #调用x()就是执行g()函数定义的代码
请注意区分返回函数和返回值:
def myabs(): return abs # 返回函数 def myabs2(x): return abs(x) # 返回函数调用的结果,返回值是一个数值 复制代码
返回函数可以把一些计算延迟执行。例如,如果定义一个普通的求和函数:
def calc_sum(lst): return sum(lst) 复制代码
调用calc_sum()函数时,将立刻计算并得到结果:
>>> calc_sum([1, 2, 3, 4])
但是,如果返回一个函数,就可以“延迟计算”:
def calc_sum(lst): def lazy_sum(): return sum(lst) return lazy_sum 复制代码
#调用calc_sum()并没有计算出结果,而是返回函数:
>>> f = calc_sum([1, 2, 3, 4])
>>> f
<function lazy_sum at 0x1037bfaa0>
#对返回的函数进行调用时,才计算出结果:
>>> f()
10
由于可以返回函数,我们在后续代码里就可以决定到底要不要调用该函数。
请编写一个函数calc_prod(lst),它接收一个list,返回一个函数,返回函数可以计算参数的乘积。
def calc_prod(lst): def lazy_prod(): def f(x, y): return x * y return reduce(f, lst, 1) return lazy_prod f = calc_prod([1, 2, 3, 4]) print f() 复制代码
二、匿名函数
高阶函数可以接收函数做参数,有些时候,我们不需要显式地定义函数,直接传入匿名函数更方便。
在Python中,对匿名函数提供了有限支持。还是以map()函数为例,计算 f(x)=x2时,除了定义一个f(x)的函数外,还可以直接传入匿名函数:
map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]) 复制代码
[1, 4, 9, 16, 25, 36, 49, 64, 81]
通过对比可以看出,匿名函数 lambda x: x * x实际上就是:
def f(x): return x * x 复制代码
关键字lambda表示匿名函数,冒号前面的 x表示函数参数。
匿名函数有个限制,就是只能有一个表达式,不写return,返回值就是该表达式的结果。
使用匿名函数,可以不必定义函数名,直接创建一个函数对象,很多时候可以简化代码:
sorted([1, 3, 9, 5, 0], lambda x,y: -cmp(x,y)) 复制代码
[9, 5, 3, 1, 0]
返回函数的时候,也可以返回匿名函数:
myabs = lambda x: -x if x < 0 else x myabs(-1) 复制代码
利用匿名函数简化以下代码:
def is_not_empty(s): return s and len(s.strip()) > 0 filter(is_not_empty, ['test', None, '', 'str', ' ', 'END']) 复制代码
定义匿名函数时,没有return关键字,且表达式的值就是函数返回值。
参考代码:
print filter(lambda s: s and len(s.strip())>0, ['test', None, '', 'str', ' ', 'END'])
作者:zhulin1028
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。