Pythonのenum
モジュールにはこれまでにもint
とEnum
のミックスインで、.value
を使わなくてもオブジェクト自体がint
(のサブクラス)として扱えるIntEnum
がありました。
Python3.11からそれらに加えて、str
とEnum
のミックスインであるStrEnum
が実装されました。
- 3.10のドキュメントではカスタムミックスインクラスの実装例として
StrEnum
が記載されていましたが、ビルトインになったことで記載がなくなったようです。
IntEnum
と同じく、.value
を使わなくてもオブジェクトそれ自体がstr
のサブクラスなのでstr
との比較が可能です。
Python 3.11.0 (main, Oct 24 2022, 18:26:48) [MSC v.1933 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from enum import auto, StrEnum
>>> class Hoge(StrEnum):
... FOO = "FOO"
... BAR = "BAR"
...
>>> Hoge.FOO
<Hoge.FOO: 'FOO'>
>>> Hoge.BAR
<Hoge.BAR: 'BAR'>
>>> Hoge.FOO == "FOO"
True
また、識別子を自動的につけてくれるauto
関数もサポートされています。
値はアトリビュート名を小文字にしたものになります。
>>> class Fuga(StrEnum):
... FOO = auto()
... BAR = auto()
...
>>> Fuga.FOO
<Fuga.FOO: 'foo'>
>>> Fuga.BAR
<Fuga.BAR: 'bar'>
小文字にしてしまうのは「余計なお世話」感もあります。
しかし識別子を管理するものとして使うのがenum
の役割で、値に意味を持たせない使い方=ユニークでありさえすればなんでも構わないということなのでしょう。
-
Enum
のサブクラスなのにauto
を使えなくしてしまうとリスコフの置換原則に違反するため、仕様を決めないといけないということもありそうです。 - その値自体が文字列として意味があるのであれば
typing.Literal
を使う方がいいということなのでしょう。
ご興味のある方は使ってみては?