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

Python 3.9扩展Enum并保留类型提示解决mypy报错方案

枚举动态扩展的mypy类型校验解决方案

问题根因

mypy是静态类型检查工具,仅分析代码静态声明的内容,无法识别extend_enum在运行时动态添加的枚举成员,因此会抛出属性不存在的错误。

方案1:静态合并枚举(无aenum依赖,最优解)

不需要使用aenum做动态扩展,直接静态合并两个枚举的成员,mypy可完全识别所有成员,同时保留_missing_方法:

from __future__ import annotations
from enum import Enum

class FormattingType(str, Enum):
    DECIMAL = 'decimal'

# 拼接所有枚举成员
members = {item.name: item.value for item in FormattingType}
members["UNKNOWN"] = "Unknown"

# 用枚举函数式API创建类,指定基类为str、Enum
NewType = Enum("NewType", members, type=str)

# 绑定_missing_方法
@classmethod
def _missing_(cls, value: object) -> "NewType":
    return cls.UNKNOWN
NewType._missing_ = _missing_

def foo(arg1: NewType) -> None:
    if arg1 == NewType.UNKNOWN:
        print('Unknown')
    if arg1 == NewType.DECIMAL:
        print('Decimal')

该方案无需任何特殊的mypy适配,也没有第三方依赖,运行时逻辑和原有写法完全一致。

方案2:保留动态扩展的适配方案

如果必须使用extend_enum做动态扩展,可以通过提前声明成员类型解决mypy报错:

from __future__ import annotations
from enum import Enum
from aenum import extend_enum

class FormattingType(str, Enum):
    DECIMAL = 'decimal'

class NewType(str, Enum):
    UNKNOWN = 'Unknown'
    # 提前声明动态添加的成员类型,mypy会识别该属性
    DECIMAL: "NewType"

    @classmethod
    def _missing_(cls, value: object) -> NewType:
        return cls.UNKNOWN

[extend_enum(NewType, i.name, i.value) for i in FormattingType]

def foo(arg1: NewType) -> None:
    if arg1 == NewType.UNKNOWN:
        print('Unknown')
    if arg1 == NewType.DECIMAL:
        print('Decimal')

如果FormattingType成员数量较多,也可以在引用动态成员的行尾加# type: ignore[attr-defined]忽略单行走错,但是该方式会遗漏真实的属性不存在错误,不推荐优先使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 10:45:06