从已实施弃用__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。
答案 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)]