日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

return编程python_python3 第二十一章 - 函数式编程之return函数和闭包

發布時間:2023/12/1 python 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 return编程python_python3 第二十一章 - 函数式编程之return函数和闭包 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

def calc_sum(*args):

ax=0for n inargs:

ax= ax +nreturn ax

但是,如果不需要立刻求和,而是在后面的代碼中,根據需要再計算怎么辦?可以不返回求和的結果,而是返回求和的函數:

def lazy_sum(*args):defsum():

ax=0for n inargs:

ax= ax +nreturnaxreturnsum

f= lazy_sum(1, 2, 3, 4)print(f)print(f())

以上代碼,輸出:

.sum at 0x1014476a8>

10

當我們調用lazy_sum()時,返回的并不是求和結果,而是求和函數,調用函數f時,才真正計算求和的結果。

在這個例子中,我們在函數lazy_sum中又定義了函數sum,并且,內部函數sum可以引用外部函數lazy_sum的參數和局部變量,當lazy_sum返回函數sum時,相關參數和變量都保存在返回的函數中,這種稱為“閉包(Closure)”的程序結構擁有極大的威力。

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

def lazy_sum(*args):defsum():

ax=0for n inargs:

ax= ax +nreturnaxreturnsum

f1= lazy_sum(1, 2, 3, 4)

f2= lazy_sum(1, 2, 3, 4)print('f1==f2 :', f1 == f2)

以上代碼,輸出:

f1==f2 : False

f1()和f2()的調用結果互不影響。

閉包(closure)是函數式編程的重要的語法結構。下面看一個閉包的實際例子:

defline_conf(a, b):defline(x):return a * x +breturnline

line1= line_conf(1, 2)

line2= line_conf(3, 7)print(line1(5), line2(5))

這個例子中,函數line與環境變量a,b構成閉包。在創建閉包的時候,我們通過line_conf的參數a,b說明了這兩個環境變量的取值,這樣,我們就確定了函數的最終形式(y = x + 2和y = 3x + 7)。我們只需要變換參數a,b,就可以獲得不同的直線表達函數。由此,我們可以看到,閉包也具有提高代碼可復用性的作用。

如果沒有閉包,我們需要每次創建直線函數的時候同時說明a,b,x。這樣,我們就需要更多的參數傳遞,也減少了代碼的可移植性。利用閉包,我們實際上創建了泛函。line函數定義一種廣泛意義的函數。這個函數的一些方面已經確定(必須是直線),但另一些方面(比如a和b參數待定)。隨后,我們根據line_conf傳遞來的參數,通過閉包的形式,將最終函數確定下來。

閉包與并行運算

閉包有效的減少了函數所需定義的參數數目。這對于并行運算來說有重要的意義。在并行運算的環境下,我們可以讓每臺電腦負責一個函數,然后將一臺電腦的輸出和下一臺電腦的輸入串聯起來。最終,我們像流 水線一樣工作,從串聯的電腦集群一端輸入數據,從另一端輸出數據。這樣的情境最適合只有一個參數輸入的函數。閉包就可以實現這一目的。這也是函數式編程又熱起來的一個重要原因。函數式編程早在1950年代就已經存在,但應用并不廣泛。然而,我們上面描述的流水線式的工作并行集群過程,正適合函數式編程。由于函數式編程這一天然優勢,越來越多的語言也開始加入對函數式編程范式的支持。

需要注意的問題是,返回的函數并沒有立刻執行,而是直到調用了f()才執行。我們來看一個例子:

defcount():

fs=[]for i in range(1, 4):deff():return i*i

fs.append(f)returnfs

f1, f2, f3=count()print('f1():', f1())print('f2():', f2())print('f3():', f3())

在上面的例子中,每次循環,都創建了一個新的函數,然后,把創建的3個函數都返回了。

你可能認為調用f1(),f2()和f3()結果應該是1,4,9,但實際結果是:

f1(): 9f2():9f3():9

全部都是9,原因就在于返回的函數引用了變量i,但它并非立刻執行。等到3個函數都返回時,它們所引用的變量i已經變成了3,因此最終結果為9。

返回函數不要引用任何循環變量,或者后續會發生變化的變量。如果一定要引用循環變量怎么辦?方法是再創建一個函數,用該函數的參數綁定循環變量當前的值,無論該循環變量后續如何更改,已綁定到函數參數的值不變:

defcount():deff(j):defg():return j *jreturng

fs=[]for i in range(1, 4):

fs.append(f(i))#f(i)立刻被執行,因此i的當前值被傳入f()

returnfs

f1, f2, f3=count()print('f1():', f1())print('f2():', f2())print('f3():', f3())

以上代碼,輸出:

f1(): 1f2():4f3():9

總結

以上是生活随笔為你收集整理的return编程python_python3 第二十一章 - 函数式编程之return函数和闭包的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。