整数値を持つ列挙型を作成しようとしていますが、値ごとに表示しやすい文字列を返すこともできます。私はちょうど文字列にdictマッピング値を定義し、次に__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型のオブジェクトを基になる型ではなくEnum型のオブジェクトを返すようになっているようです。私は考えることができる
いくつかの回避策は、次のとおりです。
- は
Fingers._display_strings.value
として辞書を参照します。 (ただし、Fingers.__display_strings
は有効なenum値になります) - dictをクラス変数ではなくモジュール変数にする。
__str__
とfrom_string
の関数でdictを複製します(恐らくそれを一連のif
文に分割することもできます)。- dictをクラス変数にするのではなく、静的メソッド
_get_display_strings
を定義してdictを返すので、enum値にはなりません。
上記の初期コードと回避策1.
は、基本となる整数値をdictキーとして使用することに注意してください。他のオプションはすべて、dict(またはif
テスト)がクラス自体に直接ではなく別の場所に定義されている必要があるため、これらの値をクラス名で修飾する必要があります。たとえば、Fingers.THUMB
などを使用して列挙型オブジェクトを取得するか、またはFingers.THUMB.value
を使用して基礎となる整数値を取得できます(THUMB
のみではありません)。下位の整数値をdictキーとして使用する場合は、それを使用してdictを検索し、ではなく[Fingers.THUMB.value]
などのインデックスを付ける必要があります。
したがって、基本的な整数値を保持しながら、列挙型の文字列マッピングを実装するための最善の方法または最もPython的な方法は何ですか?
ありがとうございました:)私は不思議だった、あなたはどのようにこの欠損値法を使用することになっていますか?私は 'MyEnum._missing_value _(" value ")'を行うことができますが、それが意図した使用方法であるかどうかはわかりません。 'MyEnum ['value']'を使うと例外が発生する – TomDT
@TomDT:未知の値を調べると、 'Enum'機構は自動的に' _missing_value_'を呼び出します。追加の検索機能を提供するには、独自の '_missing_value_'メソッドを作成する必要があります。上記の例では、OPは 'Fingers( 'thumb')'を使って 'Fingers.THUMB'を取得したかったので、' Fingers.THUMB'は '1'なので、通常は動作しませんでした。 –
Oohhh私は、括弧[]を使ってアクセスしていましたが、私は括弧を使うことになっていました。ありがとうございました ! – TomDT