【问题标题】:Partial inheritance - inheriting some functionality, minus a problematic method部分继承 - 继承一些功能,减去有问题的方法
【发布时间】:2014-10-25 19:19:45
【问题描述】:

当从实现了已弃用的__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__  

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

这个问题来自this one

【问题讨论】:

    标签: python python-2.7 inheritance monkeypatching


    【解决方案1】:

    你不能,不能在 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)]
    

    【讨论】:

    • 你能以某种方式从 MRO 中删除 __getslice__ 吗?
    • 您的示例中的覆盖是否与我在问题中显示的覆盖行为相同?为什么它更可取?
    • @wim:不,你不能。没有办法假装方法不存在。
    • @wim:我更喜欢创建一个slice() 对象,而不是让 Python 来做;在后台self[start:stop:None] 创建该对象无论如何
    • @wim:我也发布了关于您之前问题的答案;在任何情况下,您都无法通过“删除”__getslice__ 来解决此问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 2021-12-09
    • 2022-01-12
    • 2020-01-15
    • 1970-01-01
    • 2011-04-05
    相关资源
    最近更新 更多