我試圖創建一個枚舉,該整數值具有整型值,但也可以爲每個值返回一個適合顯示的字符串。我在想,我可以只是定義一個字典映射值的字符串,然後執行__str__
和靜態構造函數與字符串參數,但有一個問題...將字符串表示與使用整數值的Python Enum關聯
(在不同的情況下,我可以剛剛做出這個枚舉的基礎數據類型是一個字符串而不是一個整數,但是這被用作枚舉數據庫表的映射,所以整數值和字符串都是有意義的,前者是主鍵)。
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
看來問題是Enum將使用所有類變量作爲枚舉值,這會導致它們返回Enum類型的對象,而不是它們的基礎類型。
我能想到的幾個解決方法包括:
- 參考字典爲
Fingers._display_strings.value
。 (然後Fingers.__display_strings
成爲一個有效的枚舉值!) - 使字典變成一個模塊變量而不是類變量。
- 在
__str__
和from_string
函數中複製字典(可能也將其拆分爲一系列if
語句)。 - 而不是使字典變成類變量,定義一個靜態方法
_get_display_strings
返回字典,所以它不會成爲一個枚舉值。
請注意,上面的初始代碼和變通方法1.
使用底層整數值作爲字典鍵。其他選項都要求字典(或if
測試)在類中直接定義的地方以外,因此它必須用類名限定這些值。因此,您只能使用Fingers.THUMB
來獲取枚舉對象,或者使用Fingers.THUMB.value
來獲取底層整數值,而不僅僅是THUMB
。如果使用底層整數值作爲字典密鑰,那麼您還必須使用它來查找字典,使用例如[Fingers.THUMB.value]
而非[Fingers.THUMB]
對其進行索引。
所以,問題是,什麼是最好或最Pythonic的方式來實現一個枚舉的字符串映射,同時保留一個基礎的整數值?
感謝您的回答:)。我想知道,你應該如何使用這種缺失值的方法?我的意思是,我可以做'MyEnum._missing_value _(「value」)',但我不確定這是否是使用它的預期方式。使用'MyEnum ['value']'會產生一個異常 – TomDT
@TomDT:當一個未知值被查找時,'Enum'機器會自動調用'_missing_value_'。您需要創建自己的'_missing_value_'方法來提供任何額外的搜索功能。在上面的例子中,OP希望使用'Fingers('thumb')'來獲取'Fingers.THUMB',這通常不會工作,因爲'Fingers.THUMB'是'1'。 –
Oohhh我看到了,我正在使用括號[]來訪問它,但我應該使用parens。謝謝 ! – TomDT