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

如何在Python中声明不可变/可变TypeVar?泛型协议场景实现

在Python中区分可变/不可变TypeVar并实现泛型协议

1. 定义区分可变/不可变的TypeVar

你可以通过TypeVar的bound参数,将其绑定到对应的抽象基类,以此明确区分可变和不可变类型:

  • 不可变类型绑定到只读抽象基类(如Sequence)
  • 可变类型绑定到可写抽象基类(如MutableSequence)

示例代码:

from typing import TypeVar, Protocol, Generic, Sequence, MutableSequence

# 绑定到不可变序列的TypeVar,仅用于只读操作场景
TImmutable = TypeVar('TImmutable', bound=Sequence)
# 绑定到可变序列的TypeVar,支持修改操作场景
TMutable = TypeVar('TMutable', bound=MutableSequence)

2. 实现泛型Protocol

结合Protocol和Generic,在协议中分别为只读方法、修改方法指定对应的TypeVar参数,静态类型检查工具(如mypy)会自动约束方法对参数的操作:

class DataHandlerProtocol(Protocol, Generic[TImmutable, TMutable]):
    # 只读方法:参数为不可变TypeVar,禁止修改操作
    def process_read_only(self, data: TImmutable) -> None:
        # 合法操作:遍历、取值
        for item in data:
            print(f"Processing: {item}")
        # 非法操作(会被类型检查工具报错):data.append("new_item")

    # 修改方法:参数为可变TypeVar,允许修改操作
    def process_modifiable(self, data: TMutable) -> None:
        # 合法操作:添加元素、排序
        data.append("new_element")
        data.sort()

3. 实现协议的具体类

当实现该协议时,你可以指定具体的可变/不可变类型:

class ConcreteDataHandler(DataHandlerProtocol[Sequence[str], list[str]]):
    def process_read_only(self, data: Sequence[str]) -> None:
        for s in data:
            print(f"Reading: {s}")

    def process_modifiable(self, data: list[str]) -> None:
        data.append("hello")
        data.sort()

额外说明

  • 如果需要支持非序列的可变/不可变类型(比如映射),可以将bound改为Mapping(只读)和MutableMapping(可变)。
  • 自定义的可变/不可变类型,只需继承对应的抽象基类(如Sequence/MutableSequence),就能被对应的TypeVar接受。
  • 静态类型检查工具会严格约束:在只读方法中尝试修改参数会触发错误,确保代码符合设计意图。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:55:03