2016-11-20 74 views
0

我經常發現自己寫的多語句表達式在運行時驗證類型的變量。例如,假設我想驗證一個特定的輸入是富對象的列表,我可能會寫下面的表達式:有沒有辦法做判斷的對象是在運行時pep484風格表達的「實例」?

assert(_isinstance(x, list) and all(_isinstance(y, Foo) for y in x)) 

我寧願能寫類似:

# pseudocode 
_assert(isinstance(x, typing.List[Foo])) 

換句話說,我要問x是美孚的實例的列表。

如果可以作出努力,這將是更好,因爲Pep484語法簡明地指定類型的嵌套結構的好方法。當然,我們都知道,這是沒有辦法的辦法Python的內置isinstance函數的工作......但只是我的夢想了一會兒:

我們都熟悉,如果外返回true的isnstance功能一個結構類型是一個類的實例:

# real python: 
isinstance(["a", "b", "c"], list) => True 

但是假設我想要做更深入的檢查:我想這樣做:

# pseudocode: 
import typing 
_isinstance("x", str) => True 
_isinstance(["a", "b", "c"], typing.List[str]) => True 
_isinstance(["a", "b", "c"], typing.List[float]) => False 
_isinstance([{"x":3}], typing.List[typing.Map[str,int]]) => True 

這樣的想法是函數如果第一個參數完全對應於Pep484風格表達式,則返回True第二個論點的離子。

當然,有些人會指出,明確的靜態和運行時類型檢查違背「鴨打字」的精神。這是真的 - 但沒有用。有時你確實想要驗證輸入的結構。隨着項目變得越來越大,你有時候想你想要什麼,你正在處理,並在其他時間類型的鴨打字給你的靈活性,肯定知道的能力。

因此,這裏是我的問題:有沒有人見過的方式來比較類型Pep484風格的表達式?如果已經有一個圖書館或功能來做它,那麼我寧願不重新發明輪子。也許打字庫已經有辦法做到這一點。請指點我吧!

+0

您已經使用'你的所有假設的例子向後isinstance'。不是說如果你翻動它,它會起作用。 'isinstance'不會做你想做的。 – ShadowRanger

+0

這是向後一個例子 - 我已經糾正了,謝謝! –

+0

在另一個示例中,您只是將其作了倒退。原型是'isinstance(OBJ,type_or_tuple_of_types)','未isinstance(type_or_tuple_of_types,OBJ)'。測試'x'是類型還是'list'的子類型是'isinstance(x,list)',而不是'isinstance(list,x)'。 – ShadowRanger

回答

-1

你可能已經做了這樣的:

def _isinstance(var, type): 
    if not isinstance(var, type): 
     return False 

    if isinstance(var, Iterable) and not isinstance(var, Generator): 
     return all(any(isinstance(v, t) for t in type.__parameters__) for v in var) 

    return True 

當然,這不是比你已經得到了很大的不同,但它給做assert(isinstance(x, List[Foo]))的「簡單」。這裏x必須是可迭代的。

注意,一個不能確定各類發電機將產生的數據,而不通過它迭代,從而喪失了所有的數據。

Python是鴨類型的和不關心類型多。如果有東西像鴨子一樣嘎嘎地響,那麼它就是Python的鴨子。

+0

嗨,說「Python是duck-typed,並不關心類型」不是特別有用。有時你必須確認類型(例如在界面邊界)。在其他時候,我們可以放鬆一下,並相信鴨子打字。我同意在一次性遍歷結構(例如Generators)的情況下,您不能驗證輸入而不渲染對象有用,但是這是真的,但是您想驗證您的類型! –

+0

@SalimFadhley,好吧,這是事實...如果你發現自己需要檢查Python中的類型,你可能會做錯誤的方式,並可能想切換到某種強類型語言,儘管在C++中爲例如,就我而言,顯式檢查類型(例如,使用「if」子句),被認爲是不好的做法。 – ForceBru

+0

我很好奇爲什麼你認爲這是一個不恰當的問題:Python 3.5.x爲了指定類型(用於類型提示)明確指定了一個迷你語言,我的問題是是否有一種方法來使用這些相同的表達式在運行時驗證類型。這不是每個項目都需要的東西,但是對我而言這將是非常方便的 - 這是一個老式的項目,它有很多結構化數據。 –

相關問題