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

标签 python python-2.7 inheritance monkeypatching

当从已实现已弃用的 __getslice__ 的父级继承时,有什么方法可以在原始切片被破坏之前获取它吗?

这是示例测试用例,我不知道如何在相关信息丢失之前重写__getslice__。可以用猴子补丁来代替吗?可以通过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__  

即使 hasattr(MyList, '__getslice__') 返回 True,del 语句也会引发 AttributeError

这个问题来自 this one

最佳答案

你不能,不能在 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对象(如果它想支持跨步,它必须这样做)。

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

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

关于python - 部分继承 - 继承一些功能,减去有问题的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25607917/

相关文章:

python - 如何在 Python 中创建多 channel .WAV 文件?

python - 调用异步任务 celery 时引发异常 : "NameError: global name * is not defined"

python - 如何在 Matplotlib 中更改文本颜色?

python - Django 可以找到我的静态文件,Pycharm 无法解析它们

python - 最高效的字典计数器

python - 当 expanded_url 不够时在 Tweepy 中完成 url(与 urllib2 集成?)

Python:从 JSON 读取正则表达式

c++ - 观察者设计模式接口(interface)契约设计问题

java - 双向水平继承可能吗?

c# - 基类 Task<> 没有空构造函数