import collections.abc
import bisect
class 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 methods
def __getitem__(self, index):
print('Getting:', index)
return self._items[index]
def __setitem__(self, index, value):
print('Setting:', index, value)
self._items[index] = value
def __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)
Len
3
>>> a.append(4)
Len
Inserting: 3 4
>>> a.append(2)
Len
Inserting: 4 2
>>> a.count(2)
Getting: 0
Getting: 1
Getting: 2
Getting: 3
Getting: 4
Getting: 5
2
>>> a.remove(3)
Getting: 0
Getting: 1
Getting: 2
Deleting: 2
>>>