流暢的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版)