2.17. 型別提示

Python 讓你能為函式參數與回傳值 標註 型別資訊。這些標註在執行期會被忽略 -- 沒有東西會檢查它們,也沒有東西會根據它們進行轉換 -- 但它們可作為給讀者與 IDE 的文件。

2.17.1. 標註語法

參數標註放在冒號之後。回傳型別放在 -> 之後、本體的冒號之前:

def greet(name: str) -> None:
    print("hello,", name)

def add(a: int, b: int) -> int:
    return a + b

def average(values: list) -> float:
    return sum(values) / len(values)

這些提示描述了 應該 傳入什麼以及 將會 回傳什麼。呼叫 add("hi", "there") 並不會引發錯誤 -- Python 仍會照樣執行本體。這些提示是一份約定,而非一項檢查。

參數可以同時具有預設值與標註:

def greet(name: str, greeting: str = "hello") -> None:
    print(greeting, name)

CPython 透過 typing 模組擁有更豐富的記法(OptionalUnion、泛型),但這些在 MicroPython 上很笨重,且在日常相機程式中鮮少需要。

2.17.2. MicroPython 在執行期的處理

MicroPython 會解析標註,然後忽略它們。相機上沒有可供匯入的 typing 模組;試圖使用 Optional[int]list[int] 將會匯入失敗,或視韌體建置版本而定,無聲地表現為一般的屬性存取。

在標註中請堅持使用單純的型別名稱(intfloatstrboolbyteslisttupledict)。它們在執行期不耗費任何成本,並能清楚地傳達意圖。

2.17.3. IDE 如何運用它們

IDE 會讀取標註以驅動工具提示、自動完成與內嵌提示。一個標註為 -> int 的函式,當游標停留在呼叫處時會將 int 顯示為其回傳型別。一個標註為 : str 的參數,會在函式本體內部對該引數自動完成字串方法。

這就是在一個會忽略標註的執行環境上撰寫標註的實際回報:從編輯器獲得更好的支援,而當指令碼在相機上執行時卻完全不耗費任何成本。

2.17.4. 變數標註

對單純賦值所做的標註以相同方式運作:

threshold: float = 0.5
name: str = "OpenMV"

這些在執行期同樣會被忽略。它們的主要用途是在右側無法清楚表明預期型別時使其變得明顯 -- 通常是當初始值是一個之後將被取代的佔位符時。