始めに
過去にPythonのenumはint等のプリミティブ型を継承すると便利という記事を投稿していました。
その後、Python3.11にてIntEnum
やStrEnum
が標準化されていることを知ったので共有します。
環境
- Python
- 3.12.4
実装
intEnum
の使用方法は次のとおりです。
from enum import IntEnum class IntInheritEnum(IntEnum): ID = 1 # 列挙型ではなく、intとして振舞うため1にアクセスできる IntInheritEnum.ID # 本来のアクセス方法 IntInheritEnum.ID.value
ちなみに、intを継承したEnumとの相違点としてはIntEnum
がReprEnum
を継承していることで、str()
で期待する値を出力してくれる点がいいですね。実運用ではあまり大きな違いはないですが。
class IntInheritEnum(IntEnum): ID = 1 class IntInheritEnum2(int, Enum): ID = 1 # ログで動作確認するときにちょっとうれしい print(IntInheritEnum.ID) # 1 print(IntInheritEnum2.ID) # IntInheritEnum2.ID from pydantic import BaseModel class Tmp(BaseModel): aaa: IntInheritEnum bbb: IntInheritEnum2 # pydanticでインスタンスをログ出力するときには効かないので微妙 # どこかのアップデートでReprEnumが使用されるようになる…? print(Tmp(aaa=IntInheritEnum.ID, bbb=IntInheritEnum2.ID)) # {'aaa': <IntInheritEnum.ID: 1>, 'bbb': <IntInheritEnum2.ID: 1>}
注意点
前回の記事でも記載した注意点ですが、Enum
の型のままint
としても振舞えるので型ヒントをつけたりすると混乱します。
# intとして振舞うのでエラーならない result: int = IntInheritEnum.ID + 10 # 型が違うのに計算できてしまうのは確かに違和感がある def add(num1: int, num2: IntInheritEnum): return num1 + num2
ソースコード
終わりに
前の継承も難しい構文ではなかったのですが、ちょっと混乱させてしまう点があったのでPythonの標準としてIntEnum
とStrEnum
を定義していただいて助かります。堂々と使える点が良いです。
参考記事
- 自作クラス型を継承する時の妥協も記載