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

如何让MyPy将TypedDict识别为兼容的dict类型?

问题描述

我定义了以下TypedDict类:

from typing import TypedDict, Any

class Appinfo(TypedDict):
    appid: int
    extended: dict[str, Any]
    config: dict[str, Any]
    depots: dict[str, Any]
    ufs: dict[str, Any]

class SteamAppInfo(TypedDict):
    appid: int
    data: dict[str, Appinfo]

随后将SteamAppInfo类型的变量传入一个期望接收dict的函数:

from functools import reduce
import operator

def dict_get_key_list(data: dict[str, Any], key_list: list[str]) -> Any:
    """根据提供的嵌套字典键列表返回字典值或None"""
    try:
        return reduce(operator.getitem, key_list, data)
    except KeyError:
        return None

代码运行正常(SteamAppInfo本质就是字典),但MyPy抛出类型错误:

error: Argument 1 to "dict_get_key_list" of "Utils" has incompatible type "SteamAppInfo"; expected "Dict[str, Any]"

请问如何让MyPy识别传入的是字典类型,无需枚举所有TypedDict或设置变量类型为Any?

解决方法

有三种简洁的方案可以解决该类型兼容问题:

1. 让TypedDict显式继承dict[str, Any]

修改SteamAppInfo的定义,让它直接继承dict[str, Any],MyPy会自动识别其为字典子类:

class SteamAppInfo(TypedDict, dict[str, Any]):
    appid: int
    data: dict[str, Appinfo]

2. 使用typing.cast临时转换类型

在调用函数时,用cast将SteamAppInfo变量转换为dict[str, Any],明确告知MyPy该变量符合参数类型要求:

from typing import cast

steam_app_info: SteamAppInfo = {"appid": 123, "data": {}}
result = dict_get_key_list(cast(dict[str, Any], steam_app_info), ["data", "some_key"])

3. 泛化函数的参数类型(推荐)

修改dict_get_key_list的参数类型,让它接受所有Mapping类型(TypedDict属于Mapping的子类),既保留类型检查能力,又支持更多键值对容器类型:

from typing import Mapping, Any
from functools import reduce
import operator

def dict_get_key_list(data: Mapping[str, Any], key_list: list[str]) -> Any:
    """根据提供的嵌套字典键列表返回字典值或None"""
    try:
        return reduce(operator.getitem, key_list, data)
    except KeyError:
        return None

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 08:45:28