collections.Iterable vs typing.Iterable 在类型注释和检查 Iterable 中

collections.Iterable vs typing.Iterable in type annotation and checking for Iterable

我发现在 Python 中 collections.Iterabletyping.Iterable 都可以用于类型注释和检查对象是否可迭代,即 isinstance(obj, collections.Iterable)isinstance(obj, typing.Iterable) 有效。我的问题是,它们之间有什么区别?在哪些情况下首选哪个?

typing.Iterable 是通用的,因此您可以在类型注释中说明它是什么,例如Iterable[int] 可迭代的整数。

可迭代的集合是一个抽象基础class。这些可以包括 extra mixin methods 以便在您创建自己的子 classes 时使接口更易于实现。

现在碰巧 Iterable 不包含任何这些 mixins,但它是其他抽象基础 classes 的接口的一部分。

从理论上讲,可迭代类型对任何一个都有效,但它使用了一些奇怪的元class 魔法来做到这一点,因此它们在所有情况下的行为方式并不完全相同。在运行时你真的不需要泛型,所以没有必要在类型注释等之外使用它。作为 superclass.

可迭代集合不太可能引起问题

所以简而言之,你应该在类型注释中使用类型可迭代,但集合可迭代作为超级class。


更新:

由于 PEP 585,从版本 3.9 开始,Python 的标准库容器类型也将能够接受类型注释的通用参数。这包括 collections.abc.Iterable class。当仅支持 Python 3.9 或更高版本时,不再有任何理由使用 typing.Iterable 并且从 typing 导入任何这些容器类型将被弃用。