Python裝飾器實現函數動態類型檢查

函數動態類型檢查的裝飾器代碼

import inspect
import functools

def typeHints(fn):
    @functools.wraps(fn)
    def wrap(*args, **kwargs):
        sig = inspect.signature(fn)
        params = sig.parameters
        # 處理kwargs:字典
        for k, v in kwargs:
            param = params[k]
            if param.annotation != inspect._empty and not isinstance(v, param.annotation):
                raise TypeError('parameter {} requires {}, but got {}'.format(k, param.annotation, type(v)))
        # 處理args:元組
        for i, x in enumerate(args):
            param = list(params.values())[i]
            if param.annotation != inspect._empty and not isinstance(x, param.annotation):
                raise TypeError('parameter {} requires {}, but got {}'.format(param.name, param.annotation, type(x)))
        ret = fn(*args, **kwargs)
        return ret
    return wrap


@typeHints
def add(x: int, y: int) -> int:
    return x + y

@typeHints
def add1(x, y:int) -> int:
    return x + y

print(add(3, 5))	# 輸出結果爲8
print(add1(1, 2))	# 輸出結果爲3

類型檢查主要使用了inspect庫。本次代碼運行環境是python3.5.2。inspect庫的使用方法在下面介紹。python

inspect模塊

檢查函數動態類型時,咱們主要使用的是inspect庫中的signature類,parameter類。能夠使用help方法查看inspect的詳細信息:程序員

import inspect
help(inspect)

inspect庫的源代碼見:/home/clg/.pyenv/versions/3.5.2/lib/python3.5/inspect.pyide

這個庫用來獲取Python動態對象的有用信息,好比本次用到的註解。函數

Signature類

Signature是inspect模塊的一個類,inspect模塊的signature函數用來獲取一個Signature對象,函數原型以下:學習

signature() - get a Signature object for the callableui

Signature類有一個屬性是OrderedDict類型的parameters,存儲的是參數名稱到參數對象(Parameter類的對象)的一個有序映射。code

Parameter類

Parameter類的對象主要用來組成signature()返回的Signature對象的parameters屬性。Parameter類有兩個經常使用的屬性:orm

  • name :str 參數的名稱
  • annotation 參數的註解,若是沒有註解,則annotation爲Parameter.empty

inspect模塊示例視頻

def add(x: int, y: int) -> int:
    return x + y

import inspect
sig = inspect.signature(add)
print(sig.parameters)
print(sig.parameters['x'])
print(sig.parameters.values())

# 輸出結果
OrderedDict([('x', <Parameter "x:int">), ('y', <Parameter "y:int">)])
x:int
odict_values([<Parameter "x:int">, <Parameter "y:int">])

odict_values相似於list,可是不支持下表操做,所以須要用list()轉化爲list以後再作下表操做。對象


記得幫我點贊哦!

精心整理了計算機各個方向的從入門、進階、實戰的視頻課程和電子書,按照目錄合理分類,總能找到你須要的學習資料,還在等什麼?快去關注下載吧!!!

resource-introduce

念念不忘,必有迴響,小夥伴們幫我點個贊吧,很是感謝。

我是職場亮哥,YY高級軟件工程師、四年工做經驗,拒絕鹹魚爭當龍頭的斜槓程序員。

聽我說,進步多,程序人生一把梭

若是有幸能幫到你,請幫我點個【贊】,給個關注,若是能順帶評論給個鼓勵,將不勝感激。

職場亮哥文章列表:更多文章

wechat-platform-guide-attention

本人全部文章、回答都與版權保護平臺有合做,著做權歸職場亮哥全部,未經受權,轉載必究!

相關文章
相關標籤/搜索