import collections.abcimport bisectclass SortedItems(collections.abc.Sequence):def __init__(self, initial=None):self._items = sorted(initial) if initial is not None else []def __getitem__(self, index):return self._items[index]def __len__(self):return len(self._items)def add(self, item):bisect.insort(self._items, item)items = SortedItems([5, 1, 3])print(list(items))print(items[0], items[-1])items.add(2)print(list(items))
[1, 3, 5]1 5[1, 2, 3, 5]
可以看到,SortedItems 跟普通的列表没什么两样,支持所有常用操作,包括索引、迭代、包含判断,甚至是切片操作。
这里面使用到了 bisect 模块,它是一个在排序列表中插入元素的高效方式。可以保证元素插入后还保持顺序。
>>> items = SortedItems()>>> import collections>>> isinstance(items, collections.Iterable)True>>> isinstance(items, collections.Sequence)True>>> isinstance(items, collections.Container)True>>> isinstance(items, collections.Sized)True>>> isinstance(items, collections.Mapping)False>>>
collections 中很多抽象类会为一些常见容器操作提供默认的实现, 这样一来你只需要实现那些你最感兴趣的方法即可。假设你的类继承自 collections.MutableSequence ,如下:
class Items(collections.MutableSequence):def __init__(self, initial=None):self._items = list(initial) if initial is not None else []# Required sequence methodsdef __getitem__(self, index):print('Getting:', index)return self._items[index]def __setitem__(self, index, value):print('Setting:', index, value)self._items[index] = valuedef __delitem__(self, index):print('Deleting:', index)del self._items[index]def insert(self, index, value):print('Inserting:', index, value)self._items.insert(index, value)def __len__(self):print('Len')return len(self._items)
如果你创建 Items 的实例,你会发现它支持几乎所有的核心列表方法 (如 append ()、remove ()、count () 等)。 下面是使用演示:
>>> a = Items([1, 2, 3])>>> len(a)Len3>>> a.append(4)LenInserting: 3 4>>> a.append(2)LenInserting: 4 2>>> a.count(2)Getting: 0Getting: 1Getting: 2Getting: 3Getting: 4Getting: 52>>> a.remove(3)Getting: 0Getting: 1Getting: 2Deleting: 2>>>
