如何在不出现类型问题的情况下子类化Python列表?
我想在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))
以下这些语句可以正常工作,即使没有重写的方法:
l = CustomList((1,2,3))
l.append(4)
l[0] = -1
l[0:2] = CustomList((10,11)) # type(l) is CustomList
这些语句只有在上面类定义中重写了方法后才能正常工作:
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
我唯一不知道怎么做的是让扩展切片返回正确的类型:
l6 = l[0:2:2] # type(l6) is list
我需要在我的类定义中添加什么,才能让l6
的类型变成CustomList
呢?
另外,除了扩展切片,还有其他列表操作会返回list
类型而不是CustomList
吗?
4 个回答
8
一个可能的解决办法是:创建一个UserList的子类,而不是直接使用list。这个方法对我有效。UserList就是为了这个目的而存在的。
27
你可能需要看看文档中的这两个部分:
- 模拟容器类型
- 模拟序列类型的额外方法(仅适用于Python 2)
补充:为了处理扩展切片,你需要让你的 __getitem__
方法能够处理切片对象(具体可以参考这里,往下看一点)。
30
首先,我建议你参考一下Björn Pollex的建议(赞一个)。
要解决这个特定的问题(type(l2 + l3) == CustomList
),你需要实现一个自定义的__add__()
方法:
def __add__(self, rhs):
return CustomList(list.__add__(self, rhs))
还有关于扩展切片的内容:
def __getitem__(self, item):
result = list.__getitem__(self, item)
try:
return CustomList(result)
except TypeError:
return result
我还建议你...
pydoc list
...在你的命令提示符下运行。你会看到list
类提供了哪些方法,这会给你一个很好的提示,告诉你需要重写哪些方法。