部分继承 - 继承一些功能,减去一个有问题的方法

时间:2014-09-01 14:22:49

标签: python python-2.7 inheritance monkeypatching

从已实施弃用__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

1 个答案:

答案 0 :(得分: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对象(如果它想支持步幅则必须执行此操作)。

您可以通过使用三元素切片表示法或传入显式__getslice__对象来完全避免使用slice()方法:

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