[TOC]
### 引入
高階函數英文叫`Higher-order function`。什么是高階函數?我們以實際代碼為例子,一步一步深入概念。
### 變量可以指向函數
以Python內置的求絕對值的函數abs()為例,調用該函數用以下代碼:
~~~
>>> abs(-10)
10
~~~
但是,如果只寫abs呢?
~~~
>>> abs
<built-in function abs>
~~~
可見,`abs(-10)`是函數調用,而`abs`是函數本身。
要獲得函數調用結果,我們可以把結果賦值給變量:
~~~
>>> x = abs(-10)
>>> x
10
~~~
但是,如果把函數本身賦值給變量呢?
~~~
>>> f = abs
>>> f
<built-in function abs>
~~~
**結論:函數本身也可以賦值給變量,即:變量可以指向函數。**
### 變量調用函數
**如果一個變量指向了一個函數,那么,可否通過該變量來調用這個函數?用代碼驗證一下:**
~~~
>>> f = abs
>>> f(-10)
10
~~~
成功!說明變量`f`現在已經指向了`abs`函數本身。直接調用`abs(`)函數和調用變量`f()`完全相同。
### 函數名也是變量
那么函數名是什么呢?函數名其實就是指向函數的變量!對于`abs()`這個函數,完全可以把函數名`abs`看成變量,它指向一個可以計算絕對值的函數!
如果把abs指向其他對象,會有什么情況發生?
~~~
>>> abs = 10
>>> abs(-10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
~~~
把`abs`指向`10`后,就無法通過`abs(-10)`調用該函數了!因為`abs`這個變量已經不指向求絕對值函數而是指向一個整數`10`!
當然實際代碼絕對不能這么寫,這里是為了說明函數名也是變量。要恢復`abs`函數,請重啟Python交互環境。
注:由于`abs`函數實際上是定義在`import builtins`模塊中的,所以要讓修改`abs`變量的指向在其它模塊也生效,要用`import builtins; builtins.abs = 10`。
### 傳入函數
既然變量可以指向函數,函數的參數能接收變量,那么一個函數就可以接收另一個函數作為參數,這種函數就稱之為高階函數。
一個最簡單的高階函數:
~~~
def add(x, y, f):
return f(x) + f(y)
~~~
當我們調用`add(-5, 6, abs)`時,參數`x`,`y`和`f`分別接收`-5,6`和`abs`,根據函數定義,我們可以推導計算過程為:
~~~
x = -5
y = 6
f = abs
f(x) + f(y) ==> abs(-5) + abs(6) ==> 11
return 11
~~~
用代碼驗證一下:
~~~
>>> add(-5, 6, abs)
11
~~~
編寫高階函數,就是讓函數的參數能夠接收別的函數。
### 小結
把函數作為參數傳入,這樣的函數稱為高階函數,函數式編程就是指這種高度抽象的編程范式。
- Python教程
- Python簡介
- 安裝Python
- Python解釋器
- 第一個 Python 程序
- 使用文本編輯器
- Python代碼運行助手
- 輸入和輸出
- 源碼
- learning.py
- Python基礎
- 數據類型和變量
- 字符串和編碼
- 使用list和tuple
- 條件判斷
- 循環
- 使用dict和set
- 函數
- 調用函數
- 定義函數
- 函數的參數
- 遞歸函數
- 高級特性
- 切片
- 迭代
- 列表生成式
- 生成器
- 迭代器
- 函數式編程
- 高階函數
- map/reduce
- filter
- sorted
- 返回函數
- 匿名函數
- 裝飾器
- 偏函數
- Python函數式編程——偏函數(來自博客)
- 模塊
- 使用模塊
- 安裝第三方模塊
- 面向對象編程
- 類和實例
- 訪問限制
- 繼承和多態
- 獲取對象信息
- 實例屬性和類屬性
- 面向對象高級編程
- 使用__slots__
- 使用@property
- 多重繼承
- 定制類
- 使用枚舉類
- 使用元類
- 錯誤、調試和測試
- 錯誤處理
- 調試
- 單元測試
- 文檔測試
- IO編程
- 文件讀寫
- StringIO和BytesIO
- 操作文件和目錄
- 序列化
- 進程和線程
- 多進程
- 多線程
- ThreadLocal
- 進程 vs. 線程
- 分布式進程
- 正則表達式
- 常用內建模塊
- datetime
- collections
- base64
- struct
- hashlib
- itertools
- contextlib
- XML
- HTMLParser
- urllib
- 常用第三方模塊
- PIL
- virtualenv
- 圖形界面
- 網絡編程
- TCP/IP簡介
- TCP編程
- UDP編程
- 電子郵件
- SMTP發送郵件
- POP3收取郵件
- 訪問數據庫
- 使用SQLite
- 使用MySQL
- 使用SQLAlchemy
- Web開發
- HTTP協議簡介
- HTML簡介
- WSGI接口
- 使用Web框架
- 使用模板
- 異步IO
- 協程
- asyncio
- async/await
- aiohttp
- 實戰
- Day 1 - 搭建開發環境
- Day 2 - 編寫Web App骨架
- Day 3 - 編寫ORM
- Day 4 - 編寫Model
- Day 5 - 編寫Web框架
- Day 6 - 編寫配置文件
- Day 7 - 編寫MVC
- Day 8 - 構建前端
- Day 9 - 編寫API
- Day 10 - 用戶注冊和登錄
- Day 11 - 編寫日志創建頁
- Day 12 - 編寫日志列表頁
- Day 13 - 提升開發效率
- Day 14 - 完成Web App
- Day 15 - 部署Web App
- Day 16 - 編寫移動App
- FAQ
- 期末總結