2011-05-19 53 views
3

我有一個自定義的序列類型。它本質上是一個列表和一個布爾標誌的包裝,我希望它能夠模擬通常的不可變序列行爲。什麼是pythonic /更快的方式來檢查自定義__getitem__方法的「關鍵」參數是否是切片?

我的問題是切片。據我所知,在Python 3的方式來實現它是有一個__getitem__(key)方法,它返回一個項目,如果%key是單個索引和切片序列如果%key是切片對象。但我應該如何區分這些情況?

我基本上有兩個假設。

sliced_list = self.wrapped_list[key] 
if isinstance(key, slice): 
    return MyCustomSequenceType(sliced_list, boolean_flag) 
return sliced_list 

但這是邪惡的,不是嗎?或

sliced_list = self.wrapped_list[key] 
try: 
    return MyCustomSequenceType(sliced_list, boolean_flag) 
except TypeError: 
    return sliced_list 

後者看起來更pythonic。它依賴於一個事實,即MyCustomSequenceType.__init__(self, datas, flag)調用LEN(DATAS),它使提高TypeError如果%datasinteger。但是,如果__init__提出TypeError爲另一個隨機問題它將無法追查。另外http://wiki.cython.org/enhancements/numpy/getitem暗示isinstance更快(實際上更容易優化)。

那我該怎麼辦?

+0

我不認爲'isinstance'在這種情況下是邪惡的。它有足夠的非邪惡用途被包含在Python中(與goto不同),這可能就是其中之一。 – 2011-05-19 12:23:43

+3

嗯,它變成了一個蠑螈。 – Evpok 2011-05-19 12:39:38

+0

嗯,我想這是邪惡的。除非你做了一些值得擁有的東西。 – 2011-05-19 16:52:58

回答

3

你可以看看標準庫,並複製那裏做了什麼。例如,calendar.py具有:

def __getitem__(self, i): 
    funcs = self._months[i] 
    if isinstance(i, slice): 
     return [f(self.format) for f in funcs] 
    else: 
     return funcs(self.format) 

其示出了兩個與isinstance通過簡單地使所述索引或切片通過對基礎列表部分地迴避問題明確的檢查。

+0

確實很明顯。那麼,我還不習慣Python stdlib組織。下次我會仔細研究一下。謝謝。 – Evpok 2011-05-19 10:46:45

+1

但我寧願跳過'else:'語句。如果'isinstance(i,slice) 'bumped'True',則第一個'return'語句已經發生,第二個將不會到達。 – Evpok 2011-05-19 10:57:09

2

這應該是isinstance(key, slice),不isinstance(key, "slice")

而且,你不應該直接調用__getitem__ - 使用[]項目符號。

至於我自己,我使用isinstance(key, slice)方法,如果我需要辨別 - slice是一個非常特別的東西,不是一件很容易將是更換另一類型的(想想看 - 如果self.wrapped_listlist,一個slice是將返回除元素或錯誤以外的唯一類型的對象)。

所以我想最終是這樣的:

sliced_list = self.wrapped_list[key] 
if isinstance(key, slice): 
    return MyCustomSequenceType(sliced_list, boolean_flag) 
return sliced_list 

進一步雖然是否需要特殊對待切片考慮;我不知道你的情況是什麼,但是當做出一個將來會影響事物的架構決策時,通常考慮一些不同的方法來做同樣的事情並評估它們並決定最好的一個(不是那樣我自己做的很多 - 我傾向於只是衝過去,然後實施和補丁......)。

+0

嗯,我認爲使用'__getitem__'是有道理的,因爲使用標準'list'並不意味着限制性,但是當然任何實現它的對象都支持括號表示法,你是對的。 如果'%key'是一個slice,並且'wrapped_list'的一個元素(如果它僅僅是一個單獨的索引),那麼特別需要處理切片是因爲需要返回'MyCustomSequenceType'實例。我想不出有更好的辦法去做。 無論如何,謝謝。我的Java開發者讚揚這種解決方案的面向類型。 – Evpok 2011-05-19 10:39:04

+0

另外我編輯問題到'isinstance(key,slice)'以避免潛在讀者混淆同樣的錯誤。 – Evpok 2011-05-19 10:52:28

相關問題