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

将适配器类传入端口触发mypy类型错误,如何修正?

问题分析与修正

你的问题核心是类型标注与实际传入对象不匹配,同时对Protocol的使用场景存在误解:

错误原因

  1. "SomePort" not callable:你给get_instance的参数port标注为SomePort,这表示它应该是SomePort的实例,但实例默认不可被调用(除非定义了__call__方法),而你在函数里执行了port(),因此mypy报错。
  2. 类型不兼容:你传入的SomeAdapter是类本身(类型为Type[SomeAdapter]),但参数标注要求的是SomePort实例,两者类型不匹配,导致第二个错误。

修正方案

你需要明确:get_instance需要接收的是一个可调用对象(这里是类的构造器),调用后能返回符合SomePort协议的实例。因此要把参数类型改为Callable[[], SomePort],表示“无参、返回SomePort实例的可调用对象”。

修正后的代码:

from typing import Protocol, Callable


class SomePort(Protocol):
    def caller(self) -> None:
        raise NotImplementedError


class SomeAdapter:
    def caller(self) -> None:
        print("Called")


class SomeController:
    @staticmethod
    def get_instance(port: Callable[[], SomePort]) -> SomePort:
        return port()


instance = SomeController.get_instance(port=SomeAdapter)
instance.caller()

可选优化:显式继承Protocol

如果想让类型关系更清晰,可以让SomeAdapter显式继承SomePort(这不是必须的,因为Protocol是结构子类型,只要方法签名匹配就会被认可):

class SomeAdapter(SomePort):
    def caller(self) -> None:
        print("Called")

这样mypy会更明确地识别SomeAdapter符合SomePort协议,同时不影响代码运行逻辑。

内容的提问来源于stack exchange,提问作者Steinn Hauser Magnússon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 07:38:14