2016-08-22 81 views
4

如何檢查嵌套抽象類的完整類型簽名?在這個例子中Python:遞歸isinstance檢查

In [4]: from typing import Sequence 

In [5]: IntSeq = Sequence[int] 

In [6]: isinstance([1], IntSeq) 
Out[6]: True 

In [7]: isinstance([1.0], IntSeq) 
Out[7]: True 

我想最後isinstance調用實際上將返回False,而只檢查該參數是一個Sequence。我想到了遞歸檢查類型,但IntSeq具有存儲嵌套類型沒有公共屬性:

In [8]: dir(IntSeq) 
Out[8]: 
['__abstractmethods__', 
'__class__', 
'__delattr__', 
'__dict__', 
'__dir__', 
'__doc__', 
'__eq__', 
'__extra__', 
'__format__', 
'__ge__', 
'__getattribute__', 
'__gt__', 
'__hash__', 
'__init__', 
'__le__', 
'__len__', 
'__lt__', 
'__module__', 
'__ne__', 
'__new__', 
'__origin__', 
'__parameters__', 
'__reduce__', 
'__reduce_ex__', 
'__repr__', 
'__setattr__', 
'__sizeof__', 
'__slots__', 
'__str__', 
'__subclasshook__', 
'__weakref__', 
'_abc_cache', 
'_abc_negative_cache', 
'_abc_negative_cache_version', 
'_abc_registry'] 

因此,它似乎並沒有很直接獲得嵌套類型。我無法在文檔中找到相關信息。

P.S. 我需要這個多重分派實現。

更新

感謝亞歷山大Huszagh和攪拌機的反饋,我們現在知道,抽象類在Python 3.5(可能)具有存儲嵌套類型的兩個屬性:__parameters____args__。前者在Linux(Ubuntu)和Darwin(OS X)下都有,儘管在Linux中它是空的。後者僅在Linux下可用,並在OS X下存儲類似__parameters__的類型。此實現細節添加了混淆。

+3

我希望近親選民解釋他的選擇:「有太多可能的答案,或者對於這種格式好的答案太長了,請添加詳細信息以縮小答案集或隔離一個問題可以在幾段中回答「。 –

+0

'isinstance([「hello」],int_seq)'也是'True'。你確定你不是在創建一個更大的問題,而是嘗試使用打字而不是簡單的類型檢查來解決問題嗎? –

+0

@DmitryTorba我想在Python中實現真正的多重分派,所以我需要分派器能夠檢查完整的類型簽名。 –

回答

2

我看到你正在嘗試使用一個仍然是臨時的模塊來實現某些東西;如果你這樣做,你肯定會遇到一個變化的界面。

攪拌器注意到__parameters__參數將參數保存到該類型;這是真的,直到,我相信3.5.1。在最新版本的Python我的git克隆(3.6.0a4+__parameters__又持有空的元組,__args__持有的論點和__origin__在其__bases__屬性中的第一項:

>>> intSeq = typing.Sequence[int] 
>>> intSeq.__args__ 
(<class 'int'>,) 
>>> intSeq.__parameters__ 
() 
>>> intSeq.__origin__ 
typing.Sequence<+T_co> 

由於3.6打字的意願時,從我從PEP 411瞭解的內容中,暫時保留並進入穩定狀態,這是您應該使用的版本來實現您的功能。

+0

謝謝你的澄清。我沒有在PEP 411中找到'輸入'的提法。你知道'__origin__'屬性中'+ T_co'的含義嗎? –

+0

是的,PEP 411不會談論哪些模塊是臨時的,這是在[PEP 0484](https://www.python.org/dev/peps/pep-0484/#abstract)摘要中介紹的模塊:-)。 '+ T_co'表示參數是協變的,你可以在同一個PEP中閱讀更多關於它的內容([協方差和反變換](https://www.python.org/dev/peps/pep-0484/#covariance-和逆變))。 –