前言
由於PEP 3107 函數註解(Function Annotations)相關中文資料極少,本人閒而無事,決定解讀一下PEP3107。此PEP由python3.0開始提出。距離上次修改有3年矣。
起因
因爲Python2.x無對函數參數與返回值註解之標準,一堆工具和庫爲彌補此問題應運而生。部分利用裝飾器對函數參數與返回值進行限制。PEP3107旨在詳述此問題,減少各位對此的錯誤理解與困惑。
基本原理
函數註解具有可選性,即可用可不用;函數註解僅僅作用在compile-time;函數註解僅僅是作爲一種描述,在第三方庫支持下才可以表示各種用途。例如:對於此段函數參數註解,爲某第三方庫所用時,可能作爲對參數的描述。def compile(source: "something compilable", filename: "where the compilable thing comes from", mode: "is this a single statement or a suite?"):
又或者,有些第三方庫用註解對函數輸入輸出作類型檢測,例如:def haul(item: Haulable, *vargs: PackAnimal) -> Distance:
然而,以上所述的作用必須依賴第三方庫,無第三方庫支持,註解毫無作用。
語法
註解必須爲python表達式,且放在默認值"=xxx"之前。而在函數定義之際,該註解同時被執行。例如:def foo(a: expression, b: expression = 5): ... def foo(*args: expression, **kwargs: expression): ...
還有就是,函數註解冒號必須緊跟參數名,不可跟括號。>>> k = 1 >>> def c(): ... global k ... k = 3 ... >>> k 1 >>> def a(ll:c()): ... pass ... >>> k 3
def foo((x1, y1: expression), (x2: expression, y2: expression)=(None, None)): ...
函數返回值註解符號爲“->”,與參數註解相似,該表達式會在函數定義之時執行。
def sum() -> expression: ...
此外,lambda表達式不能註解。
使用註解
PEP3017講,用func_annotations獲取註解。而事實上,用func.__annotations__才可獲取註解,如上。而return的值,因爲return不可以作爲參數而不產生衝突。>>> def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9): ... pass ... >>> foo <function foo at 0x7fd87074fd10> >>> dir(foo) ['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] >>> foo.__annotations__ {'a': 'x', 'c': <class 'list'>, 'b': 11, 'return': 9}
參考用途
- 類型檢測
- IDE提示
- 函數重載
- 與其他語言的接口
- Adaptation?
- 邏輯陳述函數
- 數據庫查詢影射
- 。。。。。。