如何在没有类型问题的情况下继承Python列表?

sil*_*ado 33 python list subclass

我想在Python中实现一个自定义列表类作为子类list.list为了获得所有列表操作的完全类型兼容性,我需要从基类重写的最小方法集是什么?

这个问题表明至少__getslice__需要被覆盖.从进一步的研究,也__add____mul__是必需的.所以我有这个代码:

class CustomList(list):
    def __getslice__(self,i,j):
        return CustomList(list.__getslice__(self, i, j))
    def __add__(self,other):
        return CustomList(list.__add__(self,other))
    def __mul__(self,other):
        return CustomList(list.__mul__(self,other))
Run Code Online (Sandbox Code Playgroud)

即使没有重写方法,以下语句也可以按预期工作:

l = CustomList((1,2,3))
l.append(4)                       
l[0] = -1
l[0:2] = CustomList((10,11))    # type(l) is CustomList
Run Code Online (Sandbox Code Playgroud)

这些语句仅适用于上述类定义中的重写方法:

l3 = l + CustomList((4,5,6))    # type(l3) is CustomList
l4 = 3*l                        # type(l4) is CustomList
l5 = l[0:2]                     # type(l5) is CustomList
Run Code Online (Sandbox Code Playgroud)

我唯一不知道如何实现的是使扩展切片返回正确的类型:

l6 = l[0:2:2]                   # type(l6) is list
Run Code Online (Sandbox Code Playgroud)

为了获得CustomList类型,我需要添加到我的类定义中l6

此外,还有其他列表操作,而不是扩展切片,其中结果将是list类型而不是CustomList

Joh*_*web 24

首先,我建议你遵循BjörnPollex的建议(+1).

要解决此特定问题(type(l2 + l3) == CustomList),您需要实现自定义__add__():

   def __add__(self, rhs):
        return CustomList(list.__add__(self, rhs))
Run Code Online (Sandbox Code Playgroud)

对于扩展切片:

    def __getitem__(self, item):
        result = list.__getitem__(self, item)
        try:
            return CustomList(result)
        except TypeError:
            return result
Run Code Online (Sandbox Code Playgroud)

我也建议......

pydoc list
Run Code Online (Sandbox Code Playgroud)

...在您的命令提示符下.您将看到哪些方法list公开,这将为您提供一个很好的指示,指出您需要覆盖哪些方法.


Bjö*_*lex 21

您应该从文档中阅读以下两节:

编辑:为了处理扩展切片,你应该让你的__getitem__-method处理切片对象(见这里,稍微向下).


Ric*_*ves 8

可能的一刀切解决方案:子类化 UserList 而不是 list。(为我工作。)这就是 UserList 的用途。