關於Python一等函式的一點實踐

阿狸不歌發表於2019-06-11

流暢的Python

在 Python 中,函式是一等物件。程式語言理論家把“一等物件”定義為滿足下述條件的程式實體:

  • 在執行時建立

  • 能賦值給變數或資料結構中的元素

  • 能作為引數傳給函式

  • 能作為函式的返回結果

—— Guido van Rossum Python 仁慈的獨裁者 (《流暢的Python》P118)

第一條,(函式)在執行時建立,對於指令碼語言Python而言,自然不是問題;

第二條: 能賦值給變數或資料結構中的元素;

我們在PythonREPL中進行如下輸入

>>>def 判斷奇偶數(整數):              # 在執行時建立一個函式“判斷奇偶數”
...     return 整數%2 == 0
>>>以整數為引數的函式 = 判斷奇偶數     # 將函式“判斷奇偶數”賦值給變數"以整數為引數的函式"
>>>print(以整數為引數的函式)               # 將變數列印出來
<function 判斷奇偶數 at 0x1076e2510>
>>>以整數為引數的函式(9)
False

從執行結果來看,在執行時建立函式,並把函式賦值給變數沒有問題,而且被賦值之後的變數“以整數為引數的函式”就是一個可以被執行的函式了。


第三條,能作為引數傳給函式

要實現這點,我們首先得構造一個引數是函式的函式

>>> def 第一個引數是函式的函式(函式, 數值):
...     return 函式(數值)
...
>>>

然後把前面定義的函式“判斷奇偶數”當做引數傳遞給“第一個引數是函式的函式”

>>>第一個引數是函式的函式(判斷奇偶數,10)
True
>>>第一個引數是函式的函式(以整數為引數的函式, 9)    # 我們也可以把 變數“以整數為引數的函式”當引數
False

看來,以“函式”做為“函式的引數”也沒有什麼問題,雖然說起來有點拗口?。


第四條:能作為函式的返回結果

同上,要實現這一點,我們要構造一個“以函式為返回值的函式

>>>def 以函式為返回值的函式(函式):
...     return 函式
...
>>>以函式為返回值的函式(判斷奇偶數)(6)     # “以函式為返回值的函式”返回了“判斷奇偶數”
True

我們可以再構造一個有兩個引數的函式試試

>>>def 有兩個引數的函式(引數1, 引數2):
...     return 引數1 > 引數2
...
>>>以函式為返回值的函式(有兩個引數的函式)(100, 101)
False

也沒有問題!


從上面的例子我們可以看到Python作為一門指令碼語言的簡練和易用之處。

當然,有時候也會出些問題,比如,引數不滿足要求

>>> 第一個引數是函式的函式(有兩個引數的函式,10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in 第一個引數是函式的函式
TypeError: 有兩個引數的函式() missing 1 required positional argument: '引數2'

這種時候,我們就要小心謹慎一些咯?‍♀️

寫成有註解的函式有可能會給我們提個醒 ——

def 有註解的函式(文字:str, 長度:int)->str:
...     return 文字[:長度].rstrip()
>>> 有註解的函式("abcdefghijklmn",5)
'abcde'

函式註解的最大影響 ... 是為 IDE 和 lint 程式等工具中的靜態型別檢查功能提供額外的型別資訊。 —— 《流暢的Python》 P132


前述這些只是讓我們學習Python函數語言程式設計簡單瞭解一點概念,Python函數語言程式設計 可以玩出很多的花樣來。 讓我們期待這本 《Functional Python Programming, Second Edition》中文版早日出版吧! Python函數語言程式設計(第2版)

相關文章