用於標注函數的參數和返回值。
是一種在編譯時將任意 Python 表達式與函數的多個部分聯系起來的方式。
參數
identifier [: expression] [= expression]
比如:
def foo(a: str, b: int = 5):
:
用來標注 annotations。所有的 annotations 表達式只在函數定義被執行的時候執行。
附加的參數(比如 *args
和 **kwargs
)也是類似的:
def foo(*args: expression, **kwargs: expression):
比如:
def foo(**kwargs: Union[Dict[str, str], Dict[str, int]]):
返回值
在函數定義的 )
之后接上 ->
和一個 Python 表達式,比如:
def sum() -> expression:
def sum() -> int:
Lambda
Lambda 不支持 annotations。
獲取函數的 annotations
編譯完成后,函數的 annotations 可以通過函數的 func_annotations
獲取。這個屬性是一個可修改的字典,為函數參數名和 annotations 的匹配。有一個特殊的鍵 return
,用於對應返回值的 annotations。
[1] 中說是通過 func_annotations
能獲取,但實際上 func 沒有 func_annotations
這個屬性。要通過 __annotations__
獲取。
# -*- coding: utf-8 -*-
def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9):
pass
print(foo.__annotations__) # {'a': 'x', 'b': 11, 'c': <class 'list'>, 'return': 9}
使用 return
作為鍵的原因是,如果在函數參數中使用 return
會導致 SyntaxError
。
使用案例
- 類型檢查[2]
- 讓 IDE 展示一個函數的接收與返回
- 數據庫查詢匹配(類似 ORM?)
問題
- 是否可以指定 Dict 中的字段名?
- Dict 中的類型不一致如何標注,比如
{int: str, str: int}
- 如果強制實行標注,那么和靜態類型有什么不一樣?是否說明 Python 設計成動態類型是錯誤的?