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])
10
但是,如果返回一個函數,就可以“延遲計算”:
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 cal(): return reduce(lambda x,y:x*y,lst) return cal f = calc_prod([1, 2, 3, 4]) print f()
另一種方法返回list中各元素的乘積:
def calc_prod(lst): def cal(): return map(lambda x:x*x,lst) return cal f = calc_prod([1, 2, 3, 4]) print f()
結果:
24
map函數返回結果:
[1, 4, 9, 16]