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

如何正确注解使用CPython PySequence_Check的C扩展Python函数?

适配PySequence_Check的类型注解方案

方案1:自定义Protocol + 运行时检查

既然PySequence_Check的逻辑是「有__getitem__且不是dict/子类」,可以先定义一个匹配该特征的Protocol,同时在函数里补充运行时检查,和C扩展的验证逻辑对齐:

from typing import Protocol, TypeVar, Any
from collections.abc import Mapping

T = TypeVar('T')

class PySequenceLike(Protocol[T]):
    def __getitem__(self, index: int) -> T: ...

def my_c_func(my_sequence: PySequenceLike[Any]):
    # 补充运行时检查,和PySequence_Check逻辑一致
    if isinstance(my_sequence, Mapping):
        raise TypeError("dict或其子类不被允许")
    # 调用C扩展逻辑
    ...

这个方案的优势:

  • 静态类型检查工具(如mypy)会识别出拥有__getitem__的类型,匹配PySequence_Check的核心要求
  • 运行时检查和C扩展的验证逻辑完全对齐,避免静态注解与实际校验的偏差
  • 基于标准库实现,无需额外依赖

方案2:显式列举支持的序列类型

如果你的场景中,函数仅需处理几种常见序列类型(比如list、tuple、str、bytes等),可以直接用Union显式标注:

from typing import Union

def my_c_func(my_sequence: Union[list, tuple, str, bytes]):
    ...

这个方案的优点是类型提示非常明确,缺点是无法覆盖所有自定义的、符合PySequence_Check标准的序列类型,灵活性较差。

方案3:注释补充说明(最简方案)

如果不需要严格的静态类型检查,也可以保留Sequence注解,同时用注释明确实际的验证逻辑:

from typing import Sequence, Any

def my_c_func(my_sequence: Sequence[Any]):
    """
    接收符合PySequence_Check标准的序列:拥有__getitem__且不是dict/子类
    """
    ...

这种方式简单直接,但依赖开发者阅读注释,静态检查工具无法识别实际的类型限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 21:00:02