Я обнаружил, что в Python как collections.Iterable, так и typing.Iterable можно использовать в аннотации типов и проверять, является ли объект итерируемым, т.е. работают как isinstance(obj, collections.Iterable), так и isinstance(obj, typing.Iterable). У меня вопрос, в чем разница между ними? И какой из них предпочтительнее в каких ситуациях?






typing.Iterable является универсальным, поэтому вы можете указать, что это за итерация, в аннотациях вашего типа, например Iterable[int] для итерации целых чисел.
Итерируемые коллекции - это абстрактный базовый класс. Они могут включать дополнительные методы микширования, чтобы упростить реализацию интерфейса при создании собственных подклассов.
Так получилось, что Iterable не включает ни один из этих миксинов, но является частью интерфейса других абстрактных базовых классов, которые включают.
Теоретически итеративная типизация работает для обоих, но для этого используется какая-то странная магия метаклассов, поэтому они не во всех случаях ведут себя одинаково. Вам действительно не нужны универсальные шаблоны во время выполнения, поэтому нет необходимости использовать их вне аннотаций типов и тому подобного. Итерируемые коллекции с меньшей вероятностью будут вызывать проблемы в качестве суперкласса.
Короче говоря, вы должны использовать итерацию ввода в аннотациях типов, но коллекции итерацию как суперкласс.
Обновлять:
Благодаря PEP 585, начиная с версии 3.9, стандартные библиотечные типы контейнеров Python также смогут принимать универсальный аргумент для аннотаций типов. Сюда входит класс collections.abc.Iterable. При поддержке только Python 3.9 или новее, больше нет никаких причин использовать typing.Iterable, и импорт любого из этих типов контейнеров из typing будет устаревшим.
Чтобы добавить к вашему мнению о Pep 585,
typing.List[T]будет заменен простоlist[T]