1. 程式人生 > >chapter5.3類型註解及習題

chapter5.3類型註解及習題

強制 empty 數據 註解 name param items chap 不能

函數定義的弊端

動態語言的弊端,不能事先聲明類型,賦值可以是不同的類型,只有在運行時才能發現

動態語言的靈活的特性也是弊端

為解決這些問題而使用類型註解,但也只是聲明,並不能強制約束

  難發現,問題只有使用時才能發現,

  難使用,函數使用者並不能知道數據類型

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類型註解及習題