| 導航:起始頁 > Dive Into Python > 自省的威力 > 使用 lambda 函數 | << >> | ||||
深入 Python :Dive Into Python 中文版Python 從新手到專家 [Dip_5.4b_CPyUG_Release] |
|||||
Python 支持一種有趣的語法,它允許你快速定義單行的最小函數。這些叫做 lambda 的函數,是從 Lisp 借用來的,可以用在任何需要函數的地方。
>>> def f(x): ... return x*2 ... >>> f(3) 6 >>> g = lambda x: x*2>>> g(3) 6 >>> (lambda x: x*2)(3)
6
總的來說,lambda 函數可以接收任意多個參數 (包括可選參數) 并且返回單個表達式的值。lambda 函數不能包含命令,包含的表達式不能超過一個。不要試圖向 lambda 函數中塞入太多的東西;如果你需要更復雜的東西,應該定義一個普通函數,然后想讓它多長就多長。
| lambda 函數是一種風格問題。不一定非要使用它們;任何能夠使用它們的地方,都可以定義一個單獨的普通函數來進行替換。我將它們用在需要封裝特殊的、非重用代碼上,避免令我的代碼充斥著大量單行函數。 | |
apihelper.py 中的 lambda 函數:
processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)注意這里使用了 and-or 技巧的簡單形式,它是沒問題的,因為 lambda 函數在布爾環境中總是為真。(這并不意味這 lambda 函數不能返回假值。這個函數對象的布爾值為真;它的返回值可以是任何東西。)
還要注意的是使用了沒有參數的 split 函數。你已經看到過它帶一個或者兩個參數的使用,但是不帶參數它按空白進行分割。
>>> s = "this is\na\ttest">>> print s this is a test >>> print s.split()
['this', 'is', 'a', 'test'] >>> print " ".join(s.split())
'this is a test'
| 這是一個多行字符串,通過使用轉義字符的定義代替了三重引號。\n 是一個回車,\t 是一個制表符。 | |
| 不帶參數的 split 按照空白進行分割。所以三個空格、一個回車和一個制表符都是一樣的。 | |
| 通過 split 分割字符串你可以將空格統一化;然后再以單個空格作為分隔符用 join 將其重新連接起來。這也就是 info 函數將多行 doc string 合并成單行所做的事情。 |
那么 info 函數到底用這些 lambda 函數、split 函數和 and-or 技巧做了些什么呢?
processFunc 現在是一個函數,但是它到底是哪一個函數還要取決于 collapse 變量。如果 collapse 為真,processFunc(string) 將壓縮空白;否則 processFunc(string) 將返回未改變的參數。
在一個不很健壯的語言中實現它,像 Visual Basic,你很有可能要創建一個函數,接受一個字符串參數和一個 collapse 參數,并使用 if 語句確定是否壓縮空白,然后再返回相應的值。這種方式是低效的,因為函數可能需要處理每一種可能的情況。每次你調用它,它將不得不在給出你所想要的東西之前,判斷是否要壓縮空白。在 Python 中,你可以將決策邏輯拿到函數外面,而定義一個裁減過的 lambda 函數提供確切的 (唯一的) 你想要的。這種方式更為高效、更為優雅,而且很少引起那些令人討厭 (哦,想到那些參數就頭昏) 的錯誤。
<< and 和 or 的特殊性質 |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
全部放在一起 >> |