单类Python列表

0 投票
1 回答
545 浏览
提问于 2025-04-18 06:20

如何在Python的列表对象中重写每个设置方法,以便列表中的每个项目都是特定类的实例?

考虑一下

class Index(int):
    pass


class IndexList(list):

    def __init__(self, int_list):
        for el in int_list:
            self.append(Index(el))

    def __setitem__(self, key, val):
        super(IndexList, self).__setitem__(key, Index(val))

    # override append insert etc...

有没有办法不直接重写每一个添加元素到列表的函数?我原本以为只重写 __setitem__ 就可以了。

举个例子,如果 append 没有被重写。

ilist = IndexList([1,2])
ilist.append(3)

for i in ilist:
    print(isinstance(i, Index)) # True, True, False

1 个回答

3

你需要自己实现各种功能,因为底层的C语言实现并不会在每次改变时都调用__setitem__,直接操作动态增长的C数组要高效得多。

可以看看collections的抽象基类,特别是MutableSequence这个类,了解一下有哪些方法可以改变你的列表。为了保持你的类型不变,你需要实现insertappendextend__iadd__这些方法。

更好的是,你可以使用collections.MutableSequence()类作为list的替代基类;这个类是纯Python实现的,它确实将许多方法调用转化为核心方法的调用。你只需要提供__len____getitem____setitem____delitem__insert这些方法的实现;任何在表格的抽象方法列中提到的方法都需要实现。

class IndexList(collections.MutableSequence):
    def __init__(self, int_list):
        self._list = []
        for el in int_list:
            self.append(Index(el))

    def __len__(self): return len(self._list)
    def __getitem__(self, item): return self._list[item]
    def __delitem__(self, item): del self._list[item]

    def __setitem__(self, index, value):
        self._list.key[index] = Index(value)

    def insert(self, index, value):
        self._list.insert(index, Index(value))

撰写回答