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

如何为用作TypedDict键的Python函数参数添加类型注解以消除mypy严格模式报错?

如何为用作TypedDict键的Python函数参数添加类型注解以消除mypy严格模式报错?

我最近在做代码挑战时,坚持给所有函数的参数和返回值添加类型注解,并且用mypy的严格模式来确保代码类型安全,但遇到了一个头疼的问题:当我想用一个字面量类型的参数作为TypedDict的键,在字典推导式里生成结果时,mypy会抛出类型错误。

先看我的原始代码和遇到的报错:

from typing import Literal, NotRequired, TypedDict

class Movie(TypedDict):
    Title: str
    Runtime: str
    Awards: str

class MovieData(TypedDict):
    Awards: NotRequired[str]
    Runtime: NotRequired[str]

def get_movie_field(movies: list[Movie], field: Literal['Awards', 'Runtime']) -> dict[str, MovieData]:
    return {movie['Title']: {field: movie[field]} for movie in movies}

用mypy 1.14.0严格模式检查时,会得到这个错误:

PS> mypy --strict .\program.py
program.py:13: error: Expected TypedDict key to be string literal  [misc]
Found 1 error in 1 file (checked 1 source file)

我不想直接加# type: ignore跳过检查,也尝试了很多调整:比如提前判断参数是否符合字面量值,甚至参考了重载函数的方案,但重载后的代码在严格模式下还是报同样的错:

from typing import Literal, NotRequired, TypedDict, overload

class Movie(TypedDict):
    Title: str
    Runtime: str
    Awards: str

class MovieData(TypedDict):
    Awards: NotRequired[str]
    Runtime: NotRequired[str]

@overload
def get_movie_field(movies: list[Movie], field: Literal['Awards']) -> dict[str, MovieData]:
    ...

@overload
def get_movie_field(movies: list[Movie], field: Literal['Runtime']) -> dict[str, MovieData]:
    ...

def get_movie_field(movies: list[Movie], field: Literal['Awards']|Literal['Runtime']
                    ) -> dict[str, MovieData]:
    return {movie['Title']: {field: movie[field]} for movie in movies}

运行mypy依旧报错:

PS> mypy --strict program.py
program.py:19: error: Expected TypedDict key to be string literal  [misc]
Found 1 error in 1 file (checked 1 source file)

后来我摸索出一个可行的办法——创建一个专门的辅助函数来生成MovieData实例,让mypy能明确推断出每个分支的类型:

from typing import Literal, NotRequired, TypedDict

class Movie(TypedDict):
    Title: str
    Runtime: str
    Awards: str

class MovieData(TypedDict):
    Awards: NotRequired[str]
    Runtime: NotRequired[str]

def create_MovieData(key: str, value: str) -> MovieData:
    """Creates a new TypedDict using a given key and value."""
    if key == 'Awards':
        return {'Awards': value}
    elif key == 'Runtime':
        return {'Runtime': value}

    raise ValueError(f"Invalid key: {key}")

def get_movie_field(movies: list[Movie], field: Literal['Awards', 'Runtime']) -> dict[str, MovieData]:
    return {movie['Title']: create_MovieData(field, movie[field]) for movie in movies}

这次用mypy严格模式检查,终于顺利通过了:

PS> mypy --strict program.py
Success: no issues found in 1 source file

这个方法的核心是让辅助函数的每个分支都明确返回带有字符串字面量键的MovieData,mypy能清晰识别每个分支的类型,自然就不会再抛出“期望TypedDict键为字符串字面量”的错误了。

备注:内容来源于stack exchange,提问作者James S.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 16:43:03