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

如何解决Python自定义Enum子类“index should be a string”类型报错

实现合理性说明

Python 标准 Enum 设计时,默认将 [] 运算符绑定为按成员名称查找成员的语义,和序列按下标访问的语义完全独立,因此原生没有支持整数/切片访问的设计。你的实现本身运行逻辑没有问题,只要你的项目内部明确自定义 Enum 子类的 [] 同时支持三种入参的语义,不会造成使用者的认知混淆,这个实现就是合理的。

mypy 报错解决方案

不需要使用行级 type: ignore,可以通过给元类的 __getitem__ 增加类型重载让 mypy 正确识别入参和返回值类型,修改后的代码如下:

import enum
from typing import overload, Union, TypeVar

T = TypeVar('T', bound='MyEnum')

class MyEnumMeta(enum.EnumMeta):
    @overload
    def __getitem__(self: type[T], index: int) -> T: ...
    @overload
    def __getitem__(self: type[T], index: slice) -> list[T]: ...
    @overload
    def __getitem__(self: type[T], index: str) -> T: ...

    def __getitem__(self: type[T], indexOrSlice: Union[int, slice, str]) -> Union[T, list[T]]:
        if isinstance(indexOrSlice, (int, slice)):
            return list(self)[indexOrSlice]
        return super().__getitem__(indexOrSlice)

class MyEnum(enum.Enum, metaclass=MyEnumMeta): pass

class Period(MyEnum):
    A = "a"
    B = "b"
    C = "c"

print(Period["A"])
print(Period[1])
print(Period[:2])

加上重载注解后,mypy 可以正确匹配不同入参对应的返回类型,不会再抛出「Enum index should be a string」的错误,也不会掩盖其他合法的类型问题。

mypy 问题上报说明

mypy 目前对 Enum 下标访问的校验是硬编码的规则,确实没有考虑到开发者自定义元类重写 __getitem__ 的场景,属于边界场景的漏覆盖。如果你要上报该问题,可以到 mypy 的官方代码仓库提交 Issue,附上你的最小复现代码和预期的校验行为即可。

内容的提问来源于stack exchange,提问作者Chris Santos-Lang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:57:05