如何创建支持成员属性动态初始化的Python枚举?
要实现你想要的枚举成员可动态初始化属性的效果,核心问题在于枚举成员是单例实例,且你用的NamedTuple本身是不可变类型——你之前的with_data方法没有生效,是因为_replace会返回新的NamedTuple实例,但你没有将其返回,反而试图修改枚举单例本身,这显然行不通。
下面是两种可行的实现方案:
方案一:基于原多重继承结构实现__call__方法
直接在枚举类里实现__call__魔术方法,让枚举成员可以像函数一样被调用,内部利用NamedTuple的_replace生成带有自定义属性的新实例:
from enum import Enum from typing import NamedTuple, Any class EnumAttr(NamedTuple): data: str = "" class EnumWithAttrs(EnumAttr, Enum): GREEN = EnumAttr(data="hello") BLUE = EnumAttr() def __call__(self, **kwargs: Any) -> EnumAttr: # 基于当前枚举成员的属性模板,生成新的NamedTuple实例 return self.value._replace(**kwargs) # 测试用法 a = EnumWithAttrs.BLUE(data="yellow") b = EnumWithAttrs.BLUE(data="red") print(a.data) # 输出: yellow print(b.data) # 输出: red print(a != b) # 输出: True(两个独立实例)
方案二:分离枚举标识与属性载体(更灵活)
如果你希望生成的实例能明确关联到对应的枚举成员(比如知道它属于BLUE枚举),可以把枚举和属性载体分开,用枚举成员作为工厂生成带标识的属性实例:
from enum import Enum from dataclasses import dataclass @dataclass class AttrInstance: enum_member: Enum data: str = "" class EnumWithAttrs(Enum): GREEN = "hello" BLUE = "" def __call__(self, data: str) -> AttrInstance: return AttrInstance(enum_member=self, data=data) # 测试用法 a = EnumWithAttrs.BLUE(data="yellow") b = EnumWithAttrs.BLUE(data="red") print(a.data) # 输出: yellow print(a.enum_member.name) # 输出: BLUE(明确关联枚举成员) print(a.enum_member == b.enum_member) # 输出: True
为什么之前的代码失败?
你之前的with_data方法里,self._replace(data=s)只是生成了新的NamedTuple,但没有将其返回;而且枚举成员是单例,你不能修改self本身的属性——所有对EnumWithAttrs.BLUE的引用都会指向同一个实例,修改它会影响所有地方的使用,这显然不是你想要的。
内容的提问来源于stack exchange,提问作者bzm3r
相关产品推荐
相关产品推荐

