2014-09-01 53 views
2

當從已實施已棄用__getslice__的父代繼承時,是否有任何方法可在獲得冗餘之前獲取原始片段?部分繼承 - 繼承某些功能,減去有問題的方法

這裏是示例測試用例,我不知道如何在相關信息丟失之前的某個時刻覆蓋__getslice__。可以用monkeypatching來完成嗎?它可以通過cpython擴展完成嗎?

from unittest import TestCase 
from mock import patch 
import sys 


class BigIntSlicableList(list): 
    def __getslice__(self, start, stop): 
     return self[start:stop:None] # force fallback to __getitem__ 


class BigIntSlicableListTest(TestCase): 

    @patch.object(BigIntSlicableList, '__getitem__') 
    def test_slice_big_endpoint(self, mock): 
     mylist = BigIntSlicableList([1, 2, 3]) 
     start, stop = sys.maxint - 1, sys.maxint + 1 
     bigint_slice = slice(start, stop) 
     mylist[start:stop] 
     mock.assert_called_once_with(bigint_slice) 
     self.assertEqual(mylist[start:stop], mylist[start:stop:]) 

:我只是用list這裏爲ssce,我不是真的想做一個BigList類,但不知道如何繞過限制,當一個父類可能已經實現__getslice__

下嘗試不起作用:

class MyList(list): 
    pass 

del MyList.__getslice__ 

del語句引發AttributeError,即使hasattr(MyList, '__getslice__')返回true。

此問題依次爲this one

回答

2

您不能,而不是在C中定義的類型的monkeypatch。這是因爲list沒有__getslice__。它將填充PySequenceMethods structure中的sq_slice插槽。重寫是允許的,但是你不能讓它消失。

即使您從Python實現繼承,猴子修補會降低到從原始類中刪除__getslice__方法

您的唯一選擇是提供您自己的版本,並且包括sys.maxsize限制。我更喜歡使用slice() object對於這樣的控制裝置:

def __getslice__(self, start, stop): 
    return self[slice(start, stop)] 

提供的基本類型知道如何處理一個slice對象(它必須做的,如果它要支持步)。

mylist[start:stop:None] 
mylist[slice(start, stop)] 
+0

你能以某種方式從MRO刪除'__getslice__':

您可以通過使用三片元素符號或通過傳遞一個明確的slice()對象完全避免__getslice__方法? – wim 2014-09-01 14:35:42

+0

您的示例中的覆蓋行爲與我在問題中顯示的覆蓋行爲相同嗎?爲什麼更好? – wim 2014-09-01 14:37:19

+0

@wim:不,你不能。沒有辦法假裝這個方法不存在。 – 2014-09-01 14:38:02