2016-11-22 57 views
0

我創建了一個類,它是一個tuple包裝器,元組不支持項目突變。 我應該離開__setitem____delitem__的實現或實現像例如下面(因此屬於Refused Bequest代碼的氣味)?哪種方法更pythonic?在這種情況下,定製異常是否更好?Python:不應該使用的神奇方法

def __setitem__(self, key, value): 
    """ 
    :raise: Always. 
    :raises: TypeError 
    """ 
    self.data_set[key] = value # Raise from tuple. 

def __delitem__(self, key): 
    """ 
    :raise: Always. 
    :raises: TypeError 
    """ 
    raise TypeError("Item deletion is unsupported") # Custom exceptions thrown. 

回答

1

如果你的類應該是(根據Liskov substitution principle)適當的元組亞型,那麼它應該的行爲與元組wrt/set/del相同 - 正如Guillaume所提到的,如果你既不定義__setitem__也不定義__delitem__。我不明白這會落入「拒絕遺贈」類別。

如果你的類使用一個元組作爲它的實現的一部分,但不應該是一個適當的元組子類型,那麼做任何有意義的事情 - 但如果你不想允許項目分配/刪除,那麼最簡單的事情是不執行它們的。

+0

拒絕遺贈我的意思是這個類聲明實現'__setitem__'和'__delitem__',但它的行爲表明它不支持這些操作。 – JCode

+1

AOK。實際上(正如我提到的),如果目標是不支持項目分配和刪除,那麼確實實現這些方法是沒有意義的。 –

0

如果它們對您的自定義類有意義,則實現其中一個或另一個或兩者。

如果您實施__setitem__(),您將能夠在代碼中使用yourobject[yourindex] = yourvalue語法(使用您選擇實現的語義)。

如果實現__delitem__(),你將能夠使用del yourobject[yourindex]

這是沒有意義的顯式實現的方法只是拋出一個異常,Python會在默認情況下做到這一點:

class Test(object): 
    pass 
test = Test() 
test['foo'] = 'bar' # will call Test.__setitem__() which is not explicitly defined 

會給TypeError: 'Test' object does not support item assignment

1

雖然這是一個口味的問題,我認爲你不應該實現它們。具有__setitem__, __delitem__的類實現可變集合協議(隱式地或者甚至明確地使用collection abstract base classes)。您的類只是不支持這個接口,就是這樣,用戶既沒有理由,也沒有正確的假設它確實