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

如何让Pyright认可《流畅的Python》中的Python泛型Protocol示例?

解决Pyright对泛型Protocol检查的错误问题

你的代码能正常运行,但Pyright报错的核心原因是泛型Protocol的约束关联不明确,Pyright无法自动推断int、str、list这些内置类型符合Repeatable协议的要求。下面提供两种修改方案,均可通过Pyright检查:

方案1:明确泛型Protocol的约束绑定

修改double函数的类型变量约束,指定RT需要符合Repeatable[RT](即类型RT的实例调用__mul__后返回自身类型):

from typing import Protocol

class Repeatable[T](Protocol):
    def __mul__(self: T, repeat_count: int) -> T: 
        ...

# 关键修改:将约束从Repeatable改为Repeatable[RT]
def double[RT: Repeatable[RT]](x: RT) -> RT:
    return x * 2

if __name__ == '__main__':
    print(double(3))
    print(double('A'))
    print(double([1, 2]))

方案2:使用Python 3.11+的Self类型简化定义

如果你的Python版本是3.11或以上,可通过typing.Self替代泛型参数,让协议定义更直观,Pyright能直接识别内置类型的匹配关系:

from typing import Protocol, Self

class Repeatable(Protocol):
    # 用Self替代泛型T,明确返回自身类型
    def __mul__(self, repeat_count: int) -> Self:
        ...

def double[RT: Repeatable](x: RT) -> RT:
    return x * 2

if __name__ == '__main__':
    print(double(3))
    print(double('A'))
    print(double([1, 2]))

原理说明

Pyright对静态类型检查的要求更严格,原代码仅用Repeatable作为约束时,泛型参数的关联逻辑不清晰。修改后,无论是显式绑定Repeatable[RT],还是用Self明确返回类型,都能让Pyright确认int、str、list的__mul__方法完全符合协议签名(接受int类型的重复次数,返回自身类型),从而通过检查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 04:46:14