Enum子类预构建类变量报错:_ignore_使用问题及方案咨询
问题原因
你误用了标准库Enum的_ignore_关键字——它的作用是告诉Enum元类跳过将这些名称注册为枚举成员,但同时会把这些变量从类中删除,所以后续访问时会触发AttributeError,这是它的设计逻辑,不是bug。
标准库Enum的解决方案
要在Enum类内保留预构建的可迭代对象且不注册为枚举成员,同时支持继承,可以用__init_subclass__钩子,在子类初始化完成后自动生成这些属性:
from enum import Enum from abc import ABC class BaseEpoch(Enum, ABC): @classmethod def __init_subclass__(cls) -> None: super().__init_subclass__() # 预构建按日期排序的枚举成员列表 cls._sortedByDate = sorted(cls, key=lambda x: x.value[1]) # 预构建ID到枚举成员的映射 cls._IDmap = {member.value[0]: member for member in cls} @classmethod def sortByDate(cls): return cls._sortedByDate # 子类继承后自动生成所需属性 class Epoch(BaseEpoch): V1 = (1, '2020-01-01') V2 = (2, '2021-01-01') class AnotherEpoch(BaseEpoch): A1 = (3, '2019-01-01') A2 = (4, '2022-01-01')
这个方案的核心是:__init_subclass__会在每个子类定义完成后执行,此时Enum元类已经完成了枚举成员的注册,所以新添加的_sortedByDate和_IDmap不会被当作枚举成员处理,而是作为普通类属性保留,且能被类方法正常访问。
aenum库的简化实现
如果可以使用第三方库aenum,它的_skip_特性正好匹配你的需求:它会跳过将指定名称注册为枚举成员,但不会删除这些变量,直接保留为类属性:
from aenum import Enum class Epoch(Enum): _skip_ = ['_sortedByDate', '_IDmap'] V1 = (1, '2020-01-01') V2 = (2, '2021-01-01') # 直接在类内定义预构建对象 _sortedByDate = sorted(Epoch, key=lambda x: x.value[1]) _IDmap = {member.value[0]: member for member in Epoch} @classmethod def sortByDate(cls): return cls._sortedByDate
这样代码更简洁,无需额外的钩子方法,直接在类内完成所有逻辑,且支持继承到其他Enum子类。
内容的提问来源于stack exchange,提问作者obviouslyalive
相关产品推荐
相关产品推荐

