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

如何为Callable Protocol设置默认可调用值并解决MyPy类型错误?

解决MyPy对Callable Protocol默认参数的类型报错问题

报错原因

你的lambda _: {}类型和OnStarted协议不匹配:

  • lambda的参数类型被推断为Any,而非协议要求的Dict[str, Any]
  • lambda返回的是Dict[<nothing>, <nothing>],而非协议要求的Optional[Dict[str, Any]]

解决方案

方案1:显式定义符合协议的默认函数

直接写一个满足协议要求的普通函数作为默认值,类型推断最准确:

from typing import Protocol, Dict, Any, Optional

class OnStarted(Protocol):
    def __call__(self, kwargs: Dict[str, Any]) -> Optional[Dict[str, Any]]: ...

def default_on_started(kwargs: Dict[str, Any]) -> Optional[Dict[str, Any]]:
    return {}

def foo(on_started: OnStarted = default_on_started):
    pass

方案2:用类型标注约束lambda

先将lambda赋值给一个标注了OnStarted类型的变量,再用该变量作为默认值:

from typing import Protocol, Dict, Any, Optional

class OnStarted(Protocol):
    def __call__(self, kwargs: Dict[str, Any]) -> Optional[Dict[str, Any]]: ...

default_on_started: OnStarted = lambda kwargs: {}

def foo(on_started: OnStarted = default_on_started):
    pass

方案3:使用cast强制转换类型

如果想直接用lambda作为默认值,可通过cast告诉MyPy它符合协议:

from typing import Protocol, Dict, Any, Optional, cast

class OnStarted(Protocol):
    def __call__(self, kwargs: Dict[str, Any]) -> Optional[Dict[str, Any]]: ...

def foo(on_started: OnStarted = cast(OnStarted, lambda _: {})):
    pass

方案4:给lambda添加完整类型注解

显式指定lambda的参数和返回类型,让MyPy正确推断:

from typing import Protocol, Dict, Any, Optional

class OnStarted(Protocol):
    def __call__(self, kwargs: Dict[str, Any]) -> Optional[Dict[str, Any]]: ...

def foo(on_started: OnStarted = lambda kwargs: {}):
    pass

注:这里lambda的参数命名为kwargs(和协议一致),返回的{}会被MyPy推断为Dict[str, Any],而Optional允许返回None或Dict,所以返回空字典是符合要求的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 17:30:04