我有一个这样的文件:
class Level(Enum):
prerequisite_level: Optional["Level"]
dependent_level: Optional["Level"]
lower_priority_levels: List["Level"]
greater_priority_levels: List["Level"]
DATA_CHECK = "data check"
DESIGN_CHECK = "design check"
ALERT = "alert"
字符串
枚举值是以特定的顺序排列的,基于每个级别,我需要能够获得前一个,下一个,以及所有的前一个和下一个。我相信我需要能够用数字索引级别来获得这些值,所以我添加了一个常量来做到这一点:
INCREASING_PRIORITY_LEVELS: List[Level] = list(Level)
for priority_level_index, threshold_level in enumerate(Level):
if priority_level_index > 0:
threshold_level.prerequisite_level = Level[priority_level_index - 1]
else:
threshold_level.prerequisite_level = None
if priority_level_index < len(Level) - 1:
threshold_level.dependent_level = Level[priority_level_index + 1]
else:
threshold_level.dependent_level = None
threshold_level.lower_priority_levels = Level[:priority_level_index]
threshold_level.greater_priority_levels = Level[priority_level_index + 1:]
型
这是一个笨拙的方法,我想去掉这个常量。我需要实现__getitem__
或其他东西来实现它吗?
4条答案
按热度按时间lokaqttq1#
你可以子类化
EnumMeta
来覆盖__getitem__
方法,并附加条件以返回一个Enum
值的列表或一个基于给定索引的特定Enum
值,并创建一个Enum
的子类,以前面提到的EnumMeta
子类作为元类,这样Enum
这个新子类的任何子类都可以根据需要进行索引:字符串
Level[1:3]
返回:型
Level[1]
返回:型
(感谢@EthanFurman指出了子类化
EnumMeta
的可行性。x33g5p2x2#
字符串
我很难理解上面的内容:...[注解澄清了前四个应该是属性,
prequisite
和dependent
分别是前一个和后一个成员]。解决方案是在初始化当前成员时修改以前的成员(技巧是在成员创建和初始化之后才将当前成员添加到父
Enum
)。下面是使用stdlib的Enum
1(Python 3.6及更高版本)的解决方案:型
用途:
型
注意:如果你不想看到两次名字,自定义的
__repr__
可以只显示枚举和成员名:型
然后你会看到:
型
1如果使用Python 3.5或更早版本,则需要使用
aenum
2。2披露:我是Python stdlib
Enum
、enum34
backport和Advanced Enumeration (aenum
)库的作者。kiayqfof3#
另一个版本建立在@blhsing的答案上,带有类型和对查找成员索引的支持。不幸的是,Mypy不完全支持元类,所以类型变量过于通用。
字符串
然后可以像往常一样声明
IndexableEnum
,并像列表一样使用索引:型
5tmbdcev4#
在使用方面实现相同结果的可能替代方案是使用
collections.namedtuple
:字符串
因此:
Level.DESIGN_CHECK
和Level[1]
都返回'design check'
,并且Level[1:3]
返回('design check', 'alert')