chapter5.3類型註解及習題
函數定義的弊端
動態語言的弊端,不能事先聲明類型,賦值可以是不同的類型,只有在運行時才能發現
動態語言的靈活的特性也是弊端
為解決這些問題而使用類型註解,但也只是聲明,並不能強制約束
難發現,問題只有使用時才能發現,
難使用,函數使用者並不能知道數據類型
Documentation string文檔說明,def後的三引號內的內容,pychram這些工具可以幫助你創建說明,慣例,不是強制標準
函數註解Function Annotations
def add(x:int,y:int) -> int,約定,不是強制性約束
Python3.5引入
對函數進行類型註解,返回值也可以註解
並不會對參數進行類型檢查
只是說明性的輔助,並不會對參數檢查
提供給第三方工具,做代碼分析,發現bug隱藏,例如 pychram會在類型錯誤時改變變量顏色
函數註解的信息,保存在 fn.__annotations__
函數的註解必不可少,
可以來類型檢查,通過編譯器
判斷實參和形參的類型是否相同
變量註解
3.6以後的版本可以對變量註解
函數參數類型檢查的思路
參數檢查一定在函數外
函數作為參數傳入,檢查函數拿到函數的實參,與形參的聲明做對比
fn.__annotations__屬性是一個字典,包括返回值類型的聲明,想要判斷位置參數,就無法和字典對應,要引入inspect模塊
inspect模塊
提取獲取對象信息的函數,可以檢查函數的類
import.inspect
sig = inspect.signature(foo) 獲取簽名,函數簽名包括函數的信息,函數名,參數類型,他所在空間及類和其他信息。
inspect 下有許多判斷方式,例如
isfunction(add) 是否是函數,
ismethod(add) 是否是類方法
isgenerator(add) 是否是叠代器
isgeneratorfunctions(add) 是否是生成器函數
isclass(add) 是否是類
ismodule 是否是模塊
isbuiltin 是否是內建函數
getdoc 獲取函數文檔
更多可查看inspect模塊
sig.parameters 獲取有序字典,包含參數類型聲明,有序字典的key是形參,value是類型聲明
Parameters 保存在元組中,是只讀的
name 參數名字
annotations 參數註解,可能沒有定義,
default 參數缺省值,可能沒有定義
empty 特殊的類,用來標記default屬性或者註釋annotation屬性的空值
kind 形參的類型
給一個函數加強功能,要求能檢查用戶輸入是否符合參數註解的要求
def check(fn): def wrap(*args,**kwargs): sig = inspect.signature(fn)#獲取簽名 params = sig.parameters#獲取參數註解 value = list(params.values()) for i,m in enumerate(args): param = value[m]#判斷位置參數 if param.annotation is not param.empty and not isinstance(m,value[i].annotation): raise TypeError #else: #print(‘ok‘) for k,v in kwargs.items():##判斷keyword參數 if params[k].annotation is not param.empty and not isinstance(v,params[k].annotation): raise TypeError #else: #print(‘okk‘) ret = fn(*args,**kwargs) return ret return wrap @check def add(x:int,y:int)->int: ret = x+y return ret add(1,y=2)
chapter5.3類型註解及習題