You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python 3.5中用Protocols模拟typing.Collection做类型注解?

用Protocols实现Python 3.5中的抽象集合类型注解

刚好碰到过类似的兼容问题,给你分享下用Protocols解决的具体方案——这也是Guido van Rossum提议的思路,完美适配你想要“抽象集合类型、不绑定具体实现”的需求。

问题背景回顾

Python 3.6+里可以直接用typing.Collection来标注返回任意集合类型,但Python 3.5不仅原生没有这个类型,连typing_extensions回溯库也没提供它。这时候Protocols就派上用场了:它能定义一套行为契约,只要某个类型实现了契约里的方法,就会被类型检查器认可,完全不用绑定具体的集合实现。

具体实现步骤

  1. 先安装typing_extensions(Python 3.5需要靠它来使用Protocol):

    pip install typing_extensions
    
  2. 定义一个抽象的集合Protocol,包含所有集合类型共有的核心方法:

    from typing_extensions import Protocol
    from typing import Any, Iterator, TypeVar
    
    T = TypeVar('T')
    
    class CollectionProtocol(Protocol[T]):
        def __contains__(self, item: Any) -> bool: ...
        def __iter__(self) -> Iterator[T]: ...
        def __len__(self) -> int: ...
    

    这里用了泛型T,可以让注解更精准,比如标注返回字符串集合就用CollectionProtocol[str],数字集合用CollectionProtocol[int]。

  3. 在函数中使用这个Protocol作为返回类型注解:

    def fetch_items() -> CollectionProtocol[str]:
        # 这里可以自由切换返回实现,类型检查完全兼容
        return ["apple", "banana", "cherry"]  # list
        # return ("apple", "banana", "cherry")  # tuple
        # return {"apple", "banana", "cherry"}  # set
        # return {"a": "apple", "b": "banana"}.values()  # dict_values
    

为什么这能解决问题?

这个CollectionProtocol复刻了collections.abc.Collection的核心行为(包含、迭代、长度),任何实现了这三个方法的类型都会被mypy等类型检查器判定为符合注解要求。不管你后续切换到哪种集合实现,都不需要修改类型注解,完全满足“抽象+灵活”的需求。

内容的提问来源于stack exchange,提问作者Tavian Barnes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:04:53