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

如何测试两个Protocol是否互为结构子类型?

验证两个Protocol的结构子类型关系

你定义了两个Protocol:

class TooComplexProtocolInNeedOfRefactoring(Protocol):
    @property
    def useful(self) -> int:
        ...
    @property
    def irrelevant1(self) -> int:
        ...
    @property
    def irrelevant2(self) -> int:
        ...
    @property
    def irrelevant3(self) -> int:
        ...
class SpecificSubProtocol(Protocol):
    @property
    def useful(self) -> int:
        ...

需要验证所有实现TooComplexProtocolInNeedOfRefactoring的类都能兼容SpecificSubProtocol(即前者是后者的结构子类型),之前直接赋值Type[SpecificSubProtocol]的方式会报错,因为Type[X]要求的是具体类,而Protocol本身是抽象类型。

以下是两种可行的验证方式:

方式一:利用函数参数的静态类型检查

通过定义一个接受SpecificSubProtocol类型参数的函数,再传入一个标注为TooComplexProtocolInNeedOfRefactoring的变量,让静态类型检查器(如mypy、pyright)自动验证兼容性:

from typing import Protocol, TypeVar

# 定义绑定到复杂Protocol的TypeVar
T = TypeVar("T", bound=TooComplexProtocolInNeedOfRefactoring)

class TooComplexProtocolInNeedOfRefactoring(Protocol):
    @property
    def useful(self) -> int:
        ...
    @property
    def irrelevant1(self) -> int:
        ...
    @property
    def irrelevant2(self) -> int:
        ...
    @property
    def irrelevant3(self) -> int:
        ...

class SpecificSubProtocol(Protocol):
    @property
    def useful(self) -> int:
        ...

# 定义接受SpecificSubProtocol的函数
def process_specific(sub: SpecificSubProtocol) -> None:
    pass

# 模拟返回符合复杂Protocol的实例的函数
def get_complex_instance() -> T:
    ...

# 传递实例给process_specific,类型检查器会验证兼容性
process_specific(get_complex_instance())

如果TooComplexProtocolInNeedOfRefactoring不是SpecificSubProtocol的结构子类型,类型检查器会抛出类似Argument 1 has incompatible type "TooComplexProtocolInNeedOfRefactoring"; expected "SpecificSubProtocol"的错误。反之则无报错,说明结构子类型关系成立。

方式二:直接使用类型断言验证

可以通过类型断言的方式让类型检查器验证两个Protocol的兼容性:

# 定义一个符合复杂Protocol的变量
complex_proto: TooComplexProtocolInNeedOfRefactoring = ...
# 断言它属于SpecificSubProtocol类型,类型检查器会验证是否兼容
specific_proto: SpecificSubProtocol = complex_proto

同样,如果兼容性不成立,类型检查器会直接报错。

关键说明

结构子类型是静态类型系统的概念,验证依赖于mypy、pyright这类静态类型检查工具,而非运行时检查。Protocol本身在运行时只是普通类,无法通过运行时代码直接验证结构子类型关系。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 17:27:22