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

Python 3.8自定义Enum基类结合auto()的失效问题排查

解决Python 3.8中自定义__new__后Enum auto()失效的问题

在Python 3.8中,当Enum子类自定义__new__方法时,auto()无法被自动解析为预期的小写枚举名称,而是保留为<enum.auto object>。这是因为默认Enum的__new__逻辑中处理auto()的代码被自定义实现覆盖了,需要手动在__new__中补充auto()的解析逻辑。

解决方案代码示例

首先是你的LowercaseEnum基类:

from enum import Enum, auto

class LowercaseEnum(str, Enum):
    def _generate_next_value_(name, start, count, last_values):
        # 让auto()生成枚举名称的小写形式
        return name.lower()

    def __new__(cls, value):
        # 基类逻辑:将值转为小写
        obj = str.__new__(cls, value.lower())
        obj._value_ = value.lower()
        return obj

正常工作的子类(无自定义__new__)

class Test(LowercaseEnum):
    FIRST = auto()
    SECOND = auto()

# 测试结果:Test.FIRST.value → 'first',符合预期

修复前有问题的子类(自定义__new__)

class Test2(LowercaseEnum):
    FIRST = auto()
    SECOND = auto()

    def __new__(cls, value, index=None):
        obj = str.__new__(cls, value)
        obj._value_ = value
        obj.index = index
        return obj

# 问题表现:Test2.FIRST.value → <enum.auto object>,而非预期的'first'

修复后的子类(添加auto()处理逻辑)

class Test2Fixed(LowercaseEnum):
    FIRST = auto()
    SECOND = auto()

    def __new__(cls, value, index=None):
        # 第一步:手动解析auto()实例
        if isinstance(value, auto):
            # 获取当前要创建的枚举成员名称
            member_names = list(cls.__members__.keys())
            current_name = member_names[len(member_names)]
            # 调用基类的_generate_next_value_生成小写名称
            value = cls._generate_next_value_(
                current_name,
                start=1,
                count=len(member_names)+1,
                last_values=[m.value for m in cls.__members__.values()]
            )
        
        # 第二步:遵循基类逻辑,将值转为小写
        value = value.lower()
        
        # 第三步:创建实例并设置自定义属性
        obj = str.__new__(cls, value)
        obj._value_ = value
        obj.index = index if index is not None else len(cls.__members__)
        return obj

# 测试结果:Test2Fixed.FIRST.value → 'first',index属性正常工作

关键逻辑说明

  1. 检测并解析auto():在自定义__new__开头判断传入的value是否为auto实例,若是则调用基类的_generate_next_value_生成对应的小写成员名称。
  2. 对齐基类逻辑:对解析后的值执行小写转换,确保和基类行为一致。
  3. 完成实例初始化:创建字符串实例并设置自定义属性,保持原有功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:27:17