首页 > 解决方案 > 使用 mypy 的“不支持的索引分配目标”,具体取决于与分配有关的类型提示时刻

问题描述

我正在尝试在我的 python 代码上输入一些内容,但出现以下 mypy 错误:“不支持的索引分配目标”

在一个简化的示例中,它相当于以下代码:

from pathlib import Path
from typing import (Literal, Mapping,
                    Optional, Union)

STRAND = Literal["+", "-"]
PATH = Union[str, Path]
fastq_files: Mapping[STRAND, Optional[PATH]] = {  # simultaneous annotation and assignment
    "+": None,
    "-": None}

reads_dir = Path("/tmp")
fastq_files["+"] = reads_dir.joinpath(  # mypy error
    "plus.fastq.gz")
fastq_files["-"] = reads_dir.joinpath(  # mypy error
    "minus.fastq.gz")

用字典值中的Nonea替换时出现错误。Path

既然是type 的值,为什么应该是 typeOptional[PATH]的值不能替换?我会认为 a与 兼容,而后者又与.PathPATHUnion[str, Path]PathUnion[str, Path]Optional[Union[str, Path]]

为什么当我在分配之前注释字典而不是在分配时注释它时错误消失了(见下文)?

from pathlib import Path
from typing import (Literal, Mapping,
                    Optional, Union)

STRAND = Literal["+", "-"]
PATH = Union[str, Path]
fastq_files: Mapping[STRAND, Optional[PATH]]  # annotation before assignment
fastq_files = {
    "+": None,
    "-": None}

reads_dir = Path("/tmp")
fastq_files["+"] = reads_dir.joinpath(  # no mypy error
    "plus.fastq.gz")
fastq_files["-"] = reads_dir.joinpath(  # no mypy error
    "minus.fastq.gz")

上面显示了 aNone可以Path在 type 的“槽”中被 a 替换Optional[Union[str, Path]]

这是否意味着当我在赋值的同时进行注释时,实际类型被“减少”到与赋值兼容的最严格的类型?(结果是“插槽”的类型更具限制性)

标签: pythontype-hintingmypyunion-types

解决方案


问题是 Mapping 应该是一个只读协议——如果你检查Mapping 的类型提示,你可以看到它实际上没有定义__setitem__方法。

如果您希望能够改变您的映射,则需要使用 Dict 或 MutableMapping。

按照另一个答案的建议切换到使用 TypedDict 也可以,因为 TypedDict 被假定为 Dict 的子类型,因此本质上是可变的。


推荐阅读