在python中,不知道函式引數型別是乙個很正常的事情,特別是在乙個大專案裡。
我見過有些專案裡,每乙個函式體的前十幾行都在檢查引數型別,這實在是太麻煩了。而且一旦引數有改動,這部分也需要改動。
下面我們用裝飾器來實現,函式引數的強制型別檢查。
首先,這個裝飾器,要接受型別引數,和指定函式引數的型別引數。也就是乙個list
和乙個dict
from functools import wraps
def typeassert(*type_args, **type_kwargs):
def decorate(func):
@wraps(func)
return func(*args, **kwargs)
return decorate
@wraps(func)
的作用請看另一篇
那麼,接下來,在裝飾器中,我們需要獲取函式引數列表,並且要和型別參數列對映。
這要借助python的乙個標準庫——inspect
這個庫一般用於python**除錯
from inspect import signature
from functools import wraps
def typeassert(*type_args, **type_kwargs):
def decorate(func):
sig = signature(func)
bound_types = sig.bind_partial(*type_args, **type_kwargs).arguments
@wraps(func)
return func(*args, **kwargs)
return decorate
上面的**中,我們使用inspect
中的signature
方法獲取了func
的signature
物件,然後使用bind_partial
方法建立了(*type_args, **type_kwargs)
到func
引數的對映(也就是乙個字典)。
接下來就簡單了,我們只需要再獲取(*args, **kwargs)
的型別,使用isinstance 函式進行比較就好。
from inspect import signature
from functools import wraps
def typeassert(*type_args, **type_kwargs):
def decorate(func):
sig = signature(func)
bound_types = sig.bind_partial(*type_args, **type_kwargs).arguments
@wraps(func)
bound_values = sig.bind(*args, **kwargs)
for name, value in bound_values.arguments.items():
if name in bound_types:
if not isinstance(value, bound_types[name]):
raise typeerror('argument {} must be {}'.format(name, bound_types[name]))
return func(*args, **kwargs)
return decorate
執行如下**
@typeassert(int, int)
def add(x, y):
return x+y
print(add("u", 2))
能看到報錯如下
traceback (most recent call last):
file "c:\users\chen\desktop\typeassert.py", line 32, in print(add("u", 2))
'argument {} must be {}'.format(name, bound_types[name])
typeerror: argument x must be
很貼心的提醒了我們哪乙個引數應該是什麼型別。你甚至可以自己改動這個裝飾器,讓它還能告訴你傳進去了什麼錯誤引數(特別是寫爬蟲的時候,引數很難掌握,一旦報錯,還得重跑一遍才知道為什麼。)
你也可以指定某乙個引數的型別,譬如
@typeassert(int, z=str)
def display(x, y, z):
print(x, y, z)
這時你會發現,y的型別就像原生的python函式一樣,什麼都行。而x必須是int
,z必須是str
。 python 函式引數型別檢查
python在3.5後引入了引數型別註解,例 def add x int,y int int 對x,y和返回值都進行注釋,為int型別 return x y注 註解是對函式引數和返回值的 注釋 沒有強制定義的作用 因為python是動態語言啊 那麼既然註解不能強制定義型別,在函式呼叫中怎麼判斷傳入的...
python引數型別檢查 Python中的型別檢查
本文中所有 均執行在python 2.7上 為什麼要進行型別檢查?總所周知,python是一門典型的動態語言,在變數定義 使用的過程中遵循duck typing,當對某一變數進行操作時才去檢查它是否支援該操作。這在大多數情況下沒有什麼問題。但有時我們希望當面對非法型別的引數的時候採取某些預設處理機制...
Python函式引數型別
函式的引數 定義函式 引數 普通引數,預設引數,可變引數 可變位置引數,可變關鍵字引數 keyword only 引數 呼叫函式 傳參 位置引數,關鍵字引數,引數結構 位置引數解構,關鍵字引數解構 普通引數 x,y def add x,y return x y 預設引數 x 1 def inc ba...