1. 程式人生 > >複習4

複習4

把函式作為引數傳入,這樣的函式稱為高階函式,函數語言程式設計就是指這
種高度抽象的程式設計正規化。

,Iterator 是惰性序列,因此通過 list()函式讓它把整個序列都
計算出來並返回一個 list

map()作為高階函式,事實上它把運算規則抽象了

Python 內建的 filter()函式用於過濾序列。
和 map()類似,filter()也接收一個函式和一個序列。和 map()不同的時,
filter()把傳入的函式依次作用於每個元素,然後根據返回值是 True 還
是 False 決定保留還是丟棄該元素。

Python 內建的 sorted()函式就可以對 list 進行排序:

,sorted()函式也是一個高階函式,它還可以接收一個 key 函式來
實現自定義的排序,例如按絕對值大小排序:

sorted([36, 5, -12, 9, -21], key=abs) [5, 9, -12, -21, 36]

key 指定的函式將作用於 list 的每一個元素上,並根據 key 函式返回的
結果進行排序。

我們給 sorted 傳入 key 函式,即可實現忽略大小寫的排序:
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower) ['about', 'bob', 'Credit', 'Zoo']

要進行反向排序,不必改動key函式,可以傳入第三個引數reverse=True:
 
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True) ['Zoo', 'Credit', 'bob', 'about']

高階函式的抽象能力是非常強大的,而且,核心
程式碼可以保持得非常簡潔。

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

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

一個函式可以返回一個計算結果,也可以返回一個函式。
返回一個函式時,牢記該函式並未執行,返回函式中不要引用任何可能
會變化的變數

關鍵字 lambda 表示匿名函式,冒號前面的 x 表示函式引數。
匿名函式有個限制,就是隻能有一個表示式,不用寫 return,返回值就
是該表示式的結果。

用匿名函式有個好處,因為函式沒有名字,不必擔心函式名衝突。此外,
匿名函式也是一個函式物件,也可以把匿名函式賦值給一個變數,再利
用變數來呼叫該函式:

,也可以把匿名函式作為返回值返回,

Python 對匿名函式的支援有限,只有一些簡單的情況下可以使用匿名函
數。

假設我們要增強 now()函式的功能,比如,在函式呼叫前後自動
列印日誌,但又不希望修改 now()函式的定義,這種在程式碼執行期間動
態增加功能的方式,稱之為“裝飾器”(Decorator)。

本質上,decorator 就是一個返回函式的高階函式。

返回的那個 wrapper()函式名字就是'wrapper',所以,需要把原始函
數的__name__等屬性複製到 wrapper()函式中,否則,有些依賴函式簽名
的程式碼執行就會出錯。

不需要編寫 wrapper.__name__ = func.__name__這樣的程式碼,Python 內建
的 functools.wraps 就是幹這個事的,所以,一個完整的 decorator 的寫
法如下:
import functools
 
def log(func):     @functools.wraps(func)     def wrapper(*args, **kw):         print('call %s():' % func.__name__)         return func(*args, **kw)     return wrapper

import functools 是匯入 functools 模組。模組的概念稍候講解。現在,
只需記住在定義 wrapper()的前面加上@functools.wraps(func)即可。

在面向物件(OOP)的設計模式中,decorator 被稱為裝飾模式。OOP
的裝飾模式需要通過繼承和組合來實現,而 Python 除了能支援 OOP 的
decorator 外,直接從語法層次支援 decorator。Python 的 decorator 可以
用函式實現,也可以用類實現。
decorator 可以增強函式的功能,定義起來雖然有點複雜,但使用起來非
常靈活和方便。

,簡單總結 functools.partial 的作用就是,把一個函式的某些引數
給固定住(也就是設定預設值),返回一個新的函式,呼叫這個新函式
會更簡單

當函式的引數個數太多,需要簡化時,使用 functools.partial 可以建立
一個新的函式,這個新函式可以固定住原函式的部分引數,從而在呼叫
時更簡單。