函式式程式設計 高階函式作為返回值

2021-08-15 17:23:52 字數 2381 閱讀 3867

高階函式除了可以接受函式作為引數外,還可以把函式作為結果值返回。

我們來實現乙個可變引數的求和。通常情況下,求和的函式是這樣定義的:

def

calc_sum

(*args):

ax = 0

for n in args:

ax = ax + n

return ax

但是,如果不需要立刻求和,而是在後面的**中,根據需要再計算怎麼辦?可以不返回求和的結果,而是返回求和的函式!

def

lazy_sum

(*args):

defsum

(): ax = 0

for n in args:

ax = ax + n

return ax

return sum

當我們呼叫lazy_sum()時,返回的並不是求和結果,而是求和函式:

>>> f = lazy_sum(1, 3, 5, 7, 9)

>>> f

sumat 0x10452f668>

呼叫函式f時,才真正計算求和的結果:

>>> f()

25

在這個例子中,我們在函式lazy_sum中又定義了函式sum,並且,內部函式sum可以引用外部函式lazy_sum的引數和區域性變數,當lazy_sum返回函式sum時,相關引數和變數都儲存在返回的函式中,這種稱為「閉包(closure)」的程式結構擁有極大的威力。

請再注意一點,當我們呼叫lazy_sum()時,每次呼叫都會返回乙個新的函式,即使傳入相同的引數:

>>> f1 = lazy_sum(1, 3, 5, 7, 9)

>>> f2 = lazy_sum(1, 3, 5, 7, 9)

>>> f1==f2

false

f1()f2()的呼叫結果互不影響。

內部函式引用外部函式的引數及區域性變數,當外部函式返回值是內部函式名時,內部函式用到的引數和變數都儲存在返回函式中,在呼叫外部函式時才賦值。

注意到返回的函式在其定義內部引用了區域性變數args,所以,當乙個函式返回了乙個函式後,其內部的區域性變數還被新函式引用,所以,閉包用起來簡單,實現起來可不容易。

另乙個需要注意的問題是,返回的函式並沒有立刻執行,而是直到呼叫了f()才執行。我們來看乙個例子:

def

count

(): fs =

for i in range(1, 4):

deff():

return i*i

return fs

f1, f2, f3 = count()

在上面的例子中,每次迴圈,都建立了乙個新的函式,然後,把建立的3個函式都返回了。

你可能認為呼叫f1()f2()f3()結果應該是149,但實際結果是:

>>> f1()

9>>> f2()

9>>> f3()

之所以全是9,是因為內部函式用了外部區域性變數i,變數i儲存在函式中,當外部函式呼叫時才賦值,所以賦值是等於3.

返回閉包時牢記的一點就是:返回函式不要引用任何迴圈變數,或者後續會發生變化的變數。

當必須要用到迴圈變數時,方法是再建立乙個函式,用該函式的引數繫結迴圈變數當前的值,無論該迴圈變數後續如何更改,已繫結到函式引數的值不變:

defcount

():... fs =

...

for i in range(1, 4):

...

deff

(j):

...

defg

():...

return j*j

...

return g

...

return fs

...

>>> f1, f2, f3 = count()

>>> f1()

1>>> f2()

4>>> f3()

9

函式作為返回值

就像常見的函式一樣,lambda 表示式可以返回乙個函式指標 委託例項 這就意味著我們能夠使用乙個 lambda 表示式來建立並返回另乙個 lambda 表示式。這種行為在很多場景下都是非常有用的。我們先來看下面這個例子 1 func saymyname string language 2 10ca...

NotesDocument 作為函式返回值的問題

some code set my doc with the return value from the function.set recipientdoc getdocinnab search string if not recipientdoc is nothing then in debug i...

指標作為函式返回值

c語言允許函式的返回值是乙個指標 位址 我們將這樣的函式稱為指標函式。下面的例子定義了乙個函式 strlong 用來返回兩個字串中較長的乙個 include include char strlong char str1,char str2 else int main 執行結果 c language ...