2010-05-19 132 views
2

我有一些Python代碼依賴於類型檢查。我會盡量用數學語言來解釋我的問題,所以很清楚。我有幾個類對應於彼此的子集並形成一個繼承鏈。Python類型檢查和繼承問題

class Real(object): 
    pass 

class Integer(Real): 
    pass 

class Natural(Integer): 
    pass 

而且我有一個包含類型的元組。其中每個對應於某個函數的域。

t1 = (Real, Real) 
t2 = (Real , Integer) 

我想這樣做某種形式的類型檢查,這樣的給定一個元組的另一如果(Natural , Natural)元組中的每個座標爲指定域的子類。例如,對於一些功能getcompatibles我想有:

getcompatibles((Real, Real)) = [ t1 ] 
getcompatibles((Real, Integer)) = [ t1, t2 ] 
getcompatibles((Natural, Natural)) = [ t1, t2 ] 
getcompatibles((Natural, Real)) = [ t1 ] 

唯一的解決辦法我能想出是通過每一個域(T1,T2)來運行通過每個類型的__subclasses__運行,檢查給定輸入是否爲isinstance爲真。

雖然這樣效率極低,但是可能有更多的Pythonic方法來做到這一點?

+0

更改is_compatible - > getcompatibles – 2010-05-19 17:10:30

回答

4
def compatible_pred(obj_types, fun_signature): 
    if len(obj_types) != len(fun_signature): return False 
    return all(issubclass(of, ft) for of, ft in zip(obj_types, fun_signature)) 

def is_compatible(obj_types, fun_signatures=(t1, t2)): 
    return [t for t in fun_signatures if compatible_pred(obj_types, t)] 

is_compatible名字的東西是謂詞的的確確是令人困惑:爲什麼不給它一個合理的名稱,如getcompatibles,使強謂語冠冕堂皇iscompatible可以用來代替什麼我必須命名爲compatible_pred

+0

精美的作品,謝謝! – 2010-05-19 16:55:51

+0

@Mark,修正,謝謝。 – 2010-05-19 17:20:25

+0

@freyrs,不客氣 - 總是樂於幫忙! – 2010-05-19 17:21:02

1

當您不必檢查類型時,請檢查類型並指望異常處理 - 使用try/except捕獲違反預期的實例。

在Python中,這是一個「懶類型」(但強類型的,我更不喜歡純粹主義者)的語言,反覆調用isinstance肯定會讓你付出代價。在面對這樣的設計問題時,我問自己的問題是「如果你不想要這個函數來處理Naturals對,你爲什麼要跟他們打電話?」假設你正在做一些以is_compatible爲基礎的條件分支,我建議你將它改爲有條件的調用。

看到你打算如何使用is_compatible的結果將允許更有針對性的答案。