我试图创建一个具有整数值的枚举,但它也可以 for each 值返回一个显示友好的字符串.我想我可以定义一个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成为模块变量而不是类变量.
- 在
__str__
和from_string
函数中复制dict(可能还会将其分解为一系列if
个语句). - 与其让dict成为类变量,不如定义一个静态方法
_get_display_strings
来返回dict,这样它就不会变成枚举值.
请注意,上面的初始代码和变通方法1.
使用底层整数值作为dict键.其他选项都要求dict(或if
测试)不是直接在类本身中定义的,因此它必须用类名限定这些值.因此,您只能使用,例如,Fingers.THUMB
来获取枚举对象,或者Fingers.THUMB.value
来获取基础整数值,而不仅仅是THUMB
.如果使用基础整数值作为dict键,那么还必须使用它来查找dict,例如,用[Fingers.THUMB.value]
而不是[Fingers.THUMB]
对其进行索引.
所以,问题是,在保留基础整数值的同时,实现枚举的字符串映射的最佳或最具python风格的方法是什么?