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

如何让MyPy正确识别自定义Enum类中描述符的实际类型

解决方案

问题根源是MyPy默认会将Enum类中定义的所有类属性识别为枚举成员,因此你定义的reactions属性被误判为Food枚举类型,才会提示不可索引。以下是两种可行的无侵入解法:

解法1:使用ClassVar标注(兼容所有版本)

Python Enum规范明确要求,标注为ClassVar的类属性不会被识别为枚举成员,MyPy完全遵循该规则。

修改步骤:

  1. 在导入类型的位置添加ClassVar的导入:
from typing import ClassVar
  1. 在定义枚举类内的Mapper属性时,明确标注为ClassVar,同时声明容器的实际类型:
class Food(NamespacedEnum):
    spam = "spam"
    eggs = "eggs"
    foo = "foo"

    # 标注为ClassVar后MyPy会自动识别为类变量,而非枚举成员
    reactions: ClassVar[dict[str, str]] = StrictEnumMapper(
        {
            spam: "I like it",
            eggs: "I don't like it...",
            foo: "I like?",
        }
    )

这种方法完全不影响运行时逻辑,仅作用于类型检查阶段,修改后MyPy就可以正确识别Food.reactions是dict类型,支持索引操作。

解法2:使用nonmember装饰器(适配Python 3.11+ / MyPy 0.940+)

Python 3.11的标准库enum模块新增了nonmember装饰器,专门用于标记类属性不属于枚举成员,MyPy从0.940版本开始支持该装饰器。使用方式如下:

from enum import nonmember

class Food(NamespacedEnum):
    spam = "spam"
    eggs = "eggs"
    foo = "foo"

    @nonmember
    reactions = StrictEnumMapper(
        {
            spam: "I like it",
            eggs: "I don't like it...",
            foo: "I like?",
        }
    )

这种方法不需要额外标注类型,MyPy会自动推导容器的实际类型。

两种方案都不需要添加# type: ignore注释,也不需要修改原有运行时逻辑,完全符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 07:45:00