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

0 投票
1 回答
28 浏览
提问于 2025-04-13 02:15

我有两个不同模块里的协议。

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,也就是说前者是后者的子类型。

我找到的所有检查结构子类型的方法都需要实例化,或者至少需要具体的类,比如

test_subtype: Type[SpecificSubProtocol] = TooComplexProtocolInNeedOfRefactoring

(“只能将具体类赋值给类型为 'type[SpecificSubProtocol]' 的变量”)

我该如何测试两个协议是否是彼此的结构子类型呢?

1 个回答

1

其实你并不需要在运行时实例化这个协议。你只需要声明一个变量,这个变量的类型就是那个协议,专门用来检查类型:

(可以在这里试试: Mypy, Pyright)

from typing import TYPE_CHECKING

if TYPE_CHECKING:
  # For Mypy, which is probably what you are using
  instance: TooComplexProtocolInNeedOfRefactoring
  # For Pyright
  instance: TooComplexProtocolInNeedOfRefactoring = ...  # type: ignore

  test_subtype: SpecificSubProtocol = instance  # this is fine

如果协议不匹配(比如试着去掉其中一个 useful() 方法),你就会看到一个“赋值时类型不兼容”的错误,或者类似的提示。

撰写回答