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

aenum.Enum中__str__返回结果触发__init__调用的原因咨询

解析你的Enum代码问题与异常行为

咱们来一步步拆解你这段基于aenum的代码里的问题,以及你遇到的无法理解的行为根源:

1. 继承顺序的核心问题

你定义的MyEnum继承顺序是str, Enum,这本身就违背了Enum类的设计规范。对于Python的Enum(包括aenum),正确的继承顺序应该是Enum在前,数据类型在后,也就是Enum, str。因为Enum是由元类控制的特殊类,先继承普通数据类型会干扰Enum元类对成员的初始化逻辑,导致内部状态混乱。

2. 错误的__new__方法实现

你重写的__new__方法完全绕过了aenum的初始化逻辑:

def __new__(cls, name, *args, **kwargs):
    member = str.__new__(cls)
    member._value_ = name
    return member

结合你设置的settings=AutoValue和init="value data1 data2",aenum本来会自动处理成员值的生成(AutoValue),并把data1、data2作为成员的额外属性。但你的__new__直接用str.__new__创建实例,还强行把_value_设为成员名称name,这直接破坏了aenum的内部机制,导致成员的真实值、额外数据都无法被正确初始化,自然会出现预期外的行为。

3. __str__赋值的无限递归风险

你把__str__设为lambda self: self,这会引发无限递归:当调用str(self)时,会触发__str__方法,而该方法返回self,Python又会尝试把self转为字符串,再次调用__str__,陷入循环。不过因为前面的__new__和继承问题,可能没有直接抛出递归错误,但会导致成员的字符串表现完全不符合预期。

正确的实现思路

如果你想让MyEnum的成员是字符串类型,且自定义__str__行为,应该这样写:

from aenum import Enum, AutoValue

class MyEnum(Enum, str, settings=AutoValue, init="value data1 data2"):
    def __str__(self):
        # 这里可以返回你想要的字符串,比如成员值、名称或自定义内容
        return self._value_
    
    # 如果需要自定义成员初始化,不要完全绕过aenum逻辑
    def __new__(cls, value, data1, data2):
        member = str.__new__(cls, value)
        member._value_ = value
        member.data1 = data1
        member.data2 = data2
        return member

# 示例成员定义
Foo = ("foo_val", "foo_data1", "foo_data2")
Bar = ("bar_val", "bar_data1", "bar_data2")

这样既保证了Enum的正常工作,又实现了自定义的字符串表现,同时保留了aenum的AutoValue和额外数据功能。

内容的提问来源于stack exchange,提问作者W. B. Reed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:28:43