我正在尝试创建一个具有整数值的枚举,但它也可以为每个值返回一个显示友好的字符串。我在想我可以定义一个 dict 映射值到字符串,然后实现 __str__
和一个带有字符串参数的静态构造函数,但是这有一个问题……
(在不同的情况下,我可以将此枚举的基础数据类型设置为字符串而不是整数,但这被用作枚举数据库表的映射,因此整数值和字符串都是有意义的,前者作为主键。)
from enum import Enum
class Fingers(Enum):
THUMB = 1
INDEX = 2
MIDDLE = 3
RING = 4
PINKY = 5
_display_strings = {
THUMB: "thumb",
INDEX: "index",
MIDDLE: "middle",
RING: "ring",
PINKY: "pinky"
}
def __str__(self):
return self._display_strings[self.value]
@classmethod
def from_string(cls, str1):
for val, str2 in cls._display_strings.items():
if str1 == str2:
return cls(val)
raise ValueError(cls.__name__ + ' has no value matching "' + str1 + '"')
转换为字符串时,出现以下错误:
>>> str(Fingers.RING)
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
str(Fingers.RING)
File "D:/src/Hacks/PythonEnums/fingers1.py", line 19, in __str__
return self._display_strings[self.value]
TypeError: 'Fingers' object is not subscriptable
问题似乎是枚举将使用所有类变量作为枚举值,这导致它们返回枚举类型的对象,而不是它们的基础类型。
我能想到的一些解决方法包括:
- 将字典称为
Fingers._display_strings.value
。 (然而Fingers.__display_strings
变成了一个有效的枚举值!) - 使 dict 成为模块变量而不是类变量。
- 在
if
__str__
和from_string
functions.42- - 与其将 dict 设为类变量,不如定义一个静态方法
_get_display_strings
来返回 dict,因此它不会成为枚举值。
请注意,上面的初始代码和解决方法 1.
使用基础整数值作为字典键。其他选项都要求 dict(或 if
测试)在类本身以外的其他地方定义,因此它必须用类名限定这些值。因此,您只能使用,例如 Fingers.THUMB
获取枚举对象,或 Fingers.THUMB.value
获取基础整数值,而不仅仅是 THUMB
如果使用基础整数值作为字典键,那么您还必须使用它来查找字典,使用例如 [Fingers.THUMB.value]
而不仅仅是 [Fingers.THUMB]
进行索引。
所以,问题是,在保留基础整数值的同时为 Enum 实现字符串映射的最佳或最 Pythonic 方法是什么?
原文由 David Scarlett 发布,翻译遵循 CC BY-SA 4.0 许可协议
这可以通过 stdlib
Enum
完成,但使用aenum
1更容易:如果您希望能够通过字符串值进行查找,那么实现新的类方法
_missing_value_
(只是_missing_
在 stdlib 中):1披露:我是 Python stdlib
Enum
、enum34
backport 和 高级枚举 (aenum
)fec3 库的作者。