collections.abc --- 容器的抽象基类¶
Added in version 3.3: 该模块曾是 collections 模块的组成部分。
本模块提供了一些 抽象基类,它们可被用于测试一个类是否提供某个特定的接口;例如,它是否为 hashable 或是否为 mapping 等。
一个接口的 issubclass() 或 isinstance() 测试采用以下三种方式之一。
- 新编写的类可以直接继承自某个抽象基类。 该类必须提供所面的抽象方法。 其他混入方法来自于继承并且可在需要时被重写。 其他方法可以被按需添加: - class C(Sequence): # 直接继承 def __init__(self): ... # ABC 所不需要的额外方法 def __getitem__(self, index): ... # 需要的抽象方法 def __len__(self): ... # 需要的抽象方法 def count(self, value): ... # 可选覆盖一个混入方法 - >>> issubclass(C, Sequence) True >>> isinstance(C(), Sequence) True 
- 已有的类和内置类可被注册为 ABC 的“虚拟子类”。 这些类应当定义完整的 API 包括所有抽象方法和所有混合方法。 这使得用户能依靠 - issubclass()或- isinstance()测试来确定完整接口是否受到支持。 此规则的例外情况是那些从 API 的其他部分自动推断出来的方法:- class D: # 无继承 def __init__(self): ... # ABC 所不需要的额外方法 def __getitem__(self, index): ... # 抽象方法 def __len__(self): ... # 抽象方法 def count(self, value): ... # 混入方法 def index(self, value): ... # 混入方法 Sequence.register(D) # 注册而非继承 - >>> issubclass(D, Sequence) True >>> isinstance(D(), Sequence) True - 在这个例子中, - D类不需要定义- __contains__,- __iter__和- __reversed__,因为 in 运算符, 迭代 逻辑和- reversed()函数会自动回退为使用- __getitem__和- __len__。
- 某些简单接口可以根据所需方法是否存在来直接识别 (除非这些方法已被设置为 - None):- class E: def __iter__(self): ... def __next__(self): ... - >>> issubclass(E, Iterable) True >>> isinstance(E(), Iterable) True - 复杂的接口不支持最后这种技术手段因为接口并不只是作为方法名称存在。 接口指明了方法之间的语义和关系,这些是无法根据特定方法名称的存在推断出来的。 例如,知道一个类提供了 - __getitem__,- __len__和- __iter__并不足以区分- Sequence和- Mapping。
Added in version 3.9: 这些抽象类现在都支持 []。 参见 GenericAlias 类型 和 PEP 585。
容器抽象基类¶
这个容器模块提供了以下 ABCs:
| 抽象基类 | 继承自 | 抽象方法 | Mixin 方法 | 
|---|---|---|---|
| 
 | |||
| 
 | |||
| 
 | |||
| 
 | 
 | ||
| 
 | |||
| 
 | 
 | ||
| 
 | |||
| 
 | |||
| 
 | |||
| 
 | 
 | ||
| 
 | 继承了  | ||
| 
 | 继承自  | ||
| 
 | 
 | ||
| 
 | 继承自  | ||
| 
 | 
 | ||
| 
 | 继承自  | ||
| 
 | |||
| 
 | |||
| 
 | |||
| 
 | |||
| 
 | |||
| 
 | 
 | ||
| 
 | |||
| 
 | 
 | ||
| 
 | 
 | ||
| 
 | 
附注
多项集抽象基类 -- 详细描述¶
- class collections.abc.Container¶
- 提供了 - __contains__()方法的抽象基类。
- class collections.abc.Hashable¶
- 提供了 - __hash__()方法的抽象基类。
- class collections.abc.Callable¶
- 用于提供 - __call__()方法的类的 ABC- 有关如何在类型标注中使用 - Callable的详细信息请参阅 标注可调用对象。
- class collections.abc.Iterable¶
- 用于提供 - __iter__()方法的类的 ABC- 检查 - isinstance(obj, Iterable)是否侦测到被注册为- Iterable或者具有- __iter__()方法的类,但它不能侦测到使用- __getitem__()方法进行迭代的类。 确定一个对象是否为 iterable 的唯一可靠方式是调用- iter(obj)。
- class collections.abc.Collection¶
- 集合了 Sized 和 Iterable 类的抽象基类。 - Added in version 3.6. 
- class collections.abc.Iterator¶
- 提供了 - __iter__()和- __next__()方法的抽象基类。参见 iterator 的定义。
- class collections.abc.Reversible¶
- 用于同时提供了 - __reversed__()方法的可迭代类的 ABC- Added in version 3.6. 
- class collections.abc.Generator¶
- 用于实现了 PEP 342 中定义的协议的 generator 类的 ABC,它通过 - send(),- throw()和- close()方法对 迭代器 进行了扩展。- 有关在类型标注中使用 - Generator的详细信息请参阅 标注生成器和协程。- Added in version 3.5. 
- class collections.abc.Sequence¶
- class collections.abc.MutableSequence¶
- class collections.abc.ByteString¶
- 只读的与可变的 序列 的抽象基类。 - 实现注意事项:某些混入方法,如 - __iter__(),- __reversed__()和- index(),会重复调用下层的- __getitem__()方法。 因此,如果- __getitem__()被实现为常数级访问速度,则混入方法的性能将为线性级;但是,如果下层的方法是线性的(例如链表就是如此),则混入方法的性能将为平方级并可能需要被重写。- index(value, start=0, stop=None)¶
- 返回首个 value 的索引。 - 如果该值不存在则会引发 - ValueError。- 对 start 和 stop 参数的支持是可选项,但建议使用。 - 在 3.5 版本发生变更: - index()方法获得对 stop 和 start 参数的支持。
 - Deprecated since version 3.12, will be removed in version 3.17: - ByteStringABC 已被弃用。- 使用 - isinstance(obj, collections.abc.Buffer)来测试- obj是否在运行时实现了 缓冲区协议。 要用于类型标注,则使用- Buffer或是显式指明你的代码所支持的类型的并集 (例如- bytes | bytearray | memoryview)。- ByteString原本是想作为- bytes和- bytearray的超类型的抽象基类提供。 不过,由于 ABC 不能有任何方法,知道一个对象是- ByteString的实例并不能真正告诉你有关该对象的任何有用信息。 其他常见缓冲区类型如- memoryview同样不能被当作是- ByteString的子类型(无论是在运行时还是对于静态类型检查器)。- 请参阅 PEP 688 了解详情。 
- class collections.abc.MappingView¶
- class collections.abc.ItemsView¶
- class collections.abc.KeysView¶
- class collections.abc.ValuesView¶
- 映射及其键和值的 视图 的抽象基类。 
- class collections.abc.Awaitable¶
- 针对 awaitable 对象的 ABC,它可被用于 - await表达式。 根据惯例所有实现都必须提供- __await__()方法。- 协程 对象和 - CoroutineABC 的实例都是这个 ABC 的实例。- 备注 - 在 CPython 中,基于生成器的协程 (使用 - @types.coroutine装饰的 生成器) 都是 可等待对象,即使它们没有- __await__()方法。 对它们使用- isinstance(gencoro, Awaitable)将返回- False。 请使用- inspect.isawaitable()来检测它们。- Added in version 3.5. 
- class collections.abc.Coroutine¶
- 用于 coroutine 兼容类的 ABC。 实现了如下定义在 协程对象 里的方法: - send(),- throw()和- close()。 根据惯例所有实现都还需要实现- __await__()。 所有的- Coroutine实例同时也是- Awaitable的实例。- 备注 - 在 CPython 中,基于生成器的协程 (使用 - @types.coroutine装饰的 生成器) 都是 可等待对象,即使它们没有- __await__()方法。 对它们使用- isinstance(gencoro, Coroutine)将返回- False。 请使用- inspect.isawaitable()来检测它们。- 有关在类型标注中使用 - Coroutine的详细信息请参阅 标注生成器和协程。 类型形参的变化和顺序与- Generator的相对应。- Added in version 3.5. 
- class collections.abc.AsyncIterable¶
- 针对提供了 - __aiter__方法的类的 ABC。 另请参阅 asynchronous iterable 的定义。- Added in version 3.5. 
- class collections.abc.AsyncIterator¶
- 提供了 - __aiter__和- __anext__方法的抽象基类。参见 asynchronous iterator 的定义。- Added in version 3.5. 
- class collections.abc.AsyncGenerator¶
- 针对实现了在 PEP 525 和 PEP 492 中定义的协议的 asynchronous generator 类的 ABC。 - 有关在类型标注中使用 - AsyncGenerator的详细信息请参阅 标注生成器和协程。- Added in version 3.6. 
- class collections.abc.Buffer¶
- 针对提供 - __buffer__()方法的类的 ABC,实现了 缓冲区协议。 参见 PEP 688。- Added in version 3.12. 
例子和配方¶
ABC 允许我们询问类或实例是否提供特定的功能,例如:
size = None
if isinstance(myvar, collections.abc.Sized):
    size = len(myvar)
有些 ABC 还适用于作为混入类,这可以更容易地开发支持容器 API 的类。 例如,要写一个支持完整 Set API 的类,只需要提供三个下层抽象方法: __contains__(), __iter__() 和 __len__()。 ABC 会提供其余的方法如 __and__() 和 isdisjoint():
class ListBasedSet(collections.abc.Set):
    ''' 空间重于速度并且不要求集合元素可哈希的
        替代性集合实现。 '''
    def __init__(self, iterable):
        self.elements = lst = []
        for value in iterable:
            if value not in lst:
                lst.append(value)
    def __iter__(self):
        return iter(self.elements)
    def __contains__(self, value):
        return value in self.elements
    def __len__(self):
        return len(self.elements)
s1 = ListBasedSet('abcdef')
s2 = ListBasedSet('defghi')
overlap = s1 & s2            # 自动支持 __and__() 方法
当把 Set 和 MutableSet 用作混入类时需注意:
- 由于某些集合操作会创建新的集合,默认的混入方法需要一种根据 iterable 创建新实例的方式。 类构造器应当具有 - ClassName(iterable)形式的签名。 这样它将被重构为一个执行- _from_iterable()的内部- classmethod,该方法会调用- cls(iterable)来产生一个新的集合。 如果- Set混入类在具有不同构造器签名的类中被使用,你将需要通过一个能根据可迭代对象参数构造新实例的类方法或常规方法来重写- _from_iterable()。
- 要重写比较运算(应该是为了提高速度,因为其语义是固定的),请重新定义 - __le__()和- __ge__(),然后其他运算将自动跟进。
- Set混入类提供了一个- _hash()方法为集合计算哈希值;但是,- __hash__()没有被定义因为并非所有集合都是 hashable 或不可变对象。 要使用混入类为集合添加可哈希性,请同时继承- Set()和- Hashable(),然后定义- __hash__ = Set._hash。
参见
- OrderedSet recipe 是基于 - MutableSet构建的一个示例。