python)の Enum 基本クラスの存在を発見したばかりで、それがどのように役立つか想像しようとしています。
信号機の状態を定義するとしましょう:
_from enum import Enum, auto
class Signal(Enum):
red = auto()
green = auto()
orange = auto()
_
プログラムのサブシステムから、色の名前を表す文字列形式の情報、たとえば_brain_detected_colour = "red"
_を受け取ったとしましょう。
この文字列を信号機の信号と比較するにはどうすればよいですか?
_brain_detected_colour is Signal.red
_は文字列ではないため、明らかに_Signal.red
_はFalse
です。
Signal(brain_detected_colour) is Signal.red
は_ValueError: 'red' is not a valid Signal
_で失敗します。
Enumのインスタンス を作成しません。 Signal(foo)
構文は、値によってEnumメンバーにアクセスするために使用されます。これは、auto()
である場合に使用されることを意図していません。
ただし、角括弧を使用してdict
の値にアクセスするように、文字列を使用して Enumメンバにアクセス を使用できます。
_Signal[brain_detected_colour] is Signal.red
_
別の可能性は、文字列をEnumメンバーのname
と比較することです:
_# Bad practice:
brain_detected_colour is Signal.red.name
_
ただし、ここでは、Enumメンバー間のIDをテストするのではなく、文字列を比較するため、同等性テストを使用することをお勧めします。
_# Better practice:
brain_detected_colour == Signal.red.name
_
(文字列間の同一性比較は string interning のおかげで機能しましたが、これは頼らない方が良いです。@ mwchaseと@Chris_Randsに私に知らせてくれてありがとう。)
さらに別の可能性は、Enumを作成するときに、メンバー値を名前として明示的に設定することです。
_class Signal(Enum):
red = "red"
green = "green"
orange = "orange"
_
(これを自動化する方法については this answer を参照してください。)
次に、Signal(brain_detected_colour) is Signal.red
が有効になります。
auto()
がその値として列挙メンバーの名前を返すようにすることは可能です(これはドキュメントの auto
セクションにあります1:
>>> class AutoName(Enum):
... def _generate_next_value_(name, start, count, last_values):
... return name
...
>>> class Ordinal(AutoName):
... NORTH = auto()
... SOUTH = auto()
... EAST = auto()
... WEST = auto()
...
>>> list(Ordinal)
[<Ordinal.NORTH: 'NORTH'>, <Ordinal.SOUTH: 'SOUTH'>, <Ordinal.EAST: 'EAST'>, <Ordinal.WEST: 'WEST'>]
1 これにはバージョンPython 3.6、またはaenum
2.0が必要です2 (aenum
は2.7以前のPythonで動作します)。
2 開示:私は Python stdlib Enum
、 enum34
バックポート 、および 高度な列挙(aenum
) ライブラリ。