PythonのEnum(列挙型)とは、「決まった選択肢の集まり」に名前を付けて1つの型として扱う仕組みで、標準ライブラリの enum モジュールで定義します。 class Status(Enum): のようにクラスを書き、Status.TODO のように使うと、タイプミスに気づきやすく、取りうる値が一目でわかるコードになります。

この記事では、Enum / IntEnum / StrEnum / Flag / IntFlag と、auto / unique / member / nonmember / verify を 1つの比較表 にまとめ、すべてのコードを Python 3.11.15 と 3.14.7 で実際に動かした実行結果 つきで解説します。基本の取り出し方に加えて、match文、JSON・SQLite・Pydantic・dataclass との組み合わせ、定数クラスや Literal 型との使い分けの判断基準(mypy の出力つき)、そして「IntEnum は int と等しくなる」「値が重複するとエイリアスになる」といった つまずきやすい点 まで1本で確認できます。

Python Enumの早見表

種類と機能の比較表

名前 追加された版 値の型 == で生の値と比べると str() の結果 主な用途
Enum 3.4 何でも False(Color.RED == 1 は False) 'Color.RED' 一般的な選択肢
IntEnum 3.4 int True(Priority.HIGH == 3) '3'(3.11以降) 大小比較・数値と混ぜて使う
StrEnum 3.11 str True(Status.TODO == "todo") 'todo' JSON・DB・APIで文字列として扱う
Flag 3.6 int(ビット) False 'Perm.READ|WRITE' 組み合わせ可能な権限・設定
IntFlag 3.6 int(ビット) True(Mode(6) == 6) '6'(3.11以降) OSの定数など int として渡す値
auto() 3.6 ― ― ― 値を自動で割り当てる(Enumは1,2,3…、StrEnumは名前の小文字、Flagは1,2,4…)
@unique 3.4 ― ― ― 値の重複(エイリアス)を禁止する
member() / nonmember() 3.11 ― ― ― 関数をメンバーにする/属性をメンバーにしない
@verify(...) 3.11 ― ― ― UNIQUE・CONTINUOUS・NAMED_FLAGS の制約チェック

操作の逆引き早見表

やりたいこと 書き方 結果の例
名前を取る Color.RED.name 'RED'
値を取る Color.RED.value 1
値からメンバーを取る Color(1) Color.RED(ないと ValueError)
名前の文字列からメンバーを取る Color["RED"] Color.RED(ないと KeyError)
全メンバーを列挙 list(Color) エイリアスを除く全メンバー
メンバー数 len(Color) 3
名前→メンバーの辞書(エイリアス込み) Color.__members__ {'RED': <Color.RED: 1>, ...}
同じメンバーか比較 c is Color.RED True / False
メンバーかどうか Color.RED in Color True
値が含まれるか(3.12以降) 1 in Color True(3.11は TypeError)

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Python Enumの使い方|StrEnum・auto・match文まで一覧解説」

Enumの基本:定義・取得・列挙・比較

Enum を継承したクラスに 名前 = 値 を並べると、それぞれが「メンバー」になります。 次のコードで、基本操作をまとめて確認します。

import sys
from enum import Enum

print(sys.version.split()[0])

class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3

print(Color.RED, repr(Color.RED), Color.RED.name, Color.RED.value)
print(Color(1), Color["RED"], getattr(Color, "BLUE"))
print(list(Color), len(Color))
print([c.name for c in Color], [c.value for c in Color])
print(Color.RED is Color(1), Color.RED == Color.RED, Color.RED == 1)
print(type(Color.RED), isinstance(Color.RED, Color))
print(Color.__members__)
print({Color.RED: "赤"}[Color.RED])

実行結果(Python 3.11.15。3.14.7でも同じ出力):

3.11.15
Color.RED <Color.RED: 1> RED 1
Color.RED Color.RED Color.BLUE
[<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 3>] 3
['RED', 'GREEN', 'BLUE'] [1, 2, 3]
True True False
<enum 'Color'> True
{'RED': <Color.RED: 1>, 'GREEN': <Color.GREEN: 2>, 'BLUE': <Color.BLUE: 3>}
赤
  • Color(1) は値から、Color["RED"] は名前から同じメンバーを取り出せます。 外部から届いた値(JSONの値やDBの文字列)を Enum に戻すときに使います。
  • 各メンバーはただ1つのオブジェクトなので、is でも == でも比較できます。
  • 普通の Enum は Color.RED == 1 が False です。 値と比べたいときは Color.RED.value == 1 と書きます。
  • メンバーはハッシュ可能なので、辞書のキーにも使えます。

存在しない値・名前、再代入、大小比較のエラー

from enum import Enum

class Color(Enum):
    RED = 1
    GREEN = 2

try:
    Color(9)
except ValueError as e:
    print("ValueError:", e)
try:
    Color["PINK"]
except KeyError as e:
    print("KeyError:", e)
try:
    Color.RED = 5
except AttributeError as e:
    print("AttributeError:", e)
try:
    Color.RED < Color.GREEN
except TypeError as e:
    print("TypeError:", e)
try:
    print(1 in Color)
except TypeError as e:
    print("TypeError:", e)

実行結果:

操作 Python 3.11.15 Python 3.14.7
Color(9) ValueError: 9 is not a valid Color 同じ
Color["PINK"] KeyError: 'PINK' 同じ
Color.RED = 5 AttributeError: cannot reassign member 'RED' 同じ
Color.RED < Color.GREEN TypeError: '<' not supported between instances of 'Color' and 'Color' 同じ
1 in Color DeprecationWarning のあと TypeError: unsupported operand type(s) for 'in': 'int' and 'EnumType' True

メンバーは再代入できないので、定数として安心して使えます。 また 1 in Color のように値で含まれるかを調べる書き方は 3.12 から使えるようになりました。 3.11 も対象にするコードでは 1 in {c.value for c in Color} と書くと、どちらでも動きます。

IntEnum・StrEnum・Flag・IntFlag の違いを実行で比べる

from enum import IntEnum, StrEnum, Flag, IntFlag, auto

class Priority(IntEnum):
    LOW = 1
    MID = 2
    HIGH = 3
print(Priority.HIGH == 3, Priority.HIGH > Priority.LOW, Priority.LOW + 1, sorted([Priority.HIGH, Priority.LOW]))
print(str(Priority.HIGH), f"{Priority.HIGH}", repr(Priority.HIGH))

class Status(StrEnum):
    TODO = auto()
    DOING = auto()
    DONE = "done"
print(Status.TODO, repr(Status.TODO), Status.TODO == "todo", f"[{Status.DOING}]", Status.DONE.upper(), Status("done"))
print("todo" in [s.value for s in Status], isinstance(Status.TODO, str))

class Perm(Flag):
    READ = auto()
    WRITE = auto()
    EXEC = auto()
rw = Perm.READ | Perm.WRITE
print(rw, repr(rw), Perm.READ in rw, Perm.EXEC in rw, bool(Perm(0)), list(rw), rw.value)
print(~Perm.READ, Perm(7))

class Mode(IntFlag):
    R = 4
    W = 2
    X = 1
print(Mode.R | Mode.W, Mode(6), Mode(6) == 6, Mode.R | 8)

実行結果(Python 3.11.15。3.14.7でも同じ出力):

True True 2 [<Priority.LOW: 1>, <Priority.HIGH: 3>]
3 3 <Priority.HIGH: 3>
todo <Status.TODO: 'todo'> True [doing] DONE done
True True
Perm.READ|WRITE <Perm.READ|WRITE: 3> True False False [<Perm.READ: 1>, <Perm.WRITE: 2>] 3
Perm.WRITE|EXEC Perm.READ|WRITE|EXEC
6 6 True 12
種類 結果から読み取れること
IntEnum > で大小比較でき、+ 1 すると普通の int(2)になる。 sorted もそのまま使える
StrEnum auto() で名前の小文字('todo')が値になる。 str のメソッド(.upper())も使え、print や f-string では値がそのまま出る
Flag | で組み合わせ、in で含まれるかを調べる。 ~ で反転、Perm(0) は偽。list(rw) で中身を分解できる
IntFlag 組み合わせても int として扱え、定義にない 8 を足しても 12 のまま保持される

どれを選ぶかの判断表

こんなとき 選ぶもの
選択肢を表したいだけ(値に意味がない) Enum + auto()
JSON・DB・APIで文字列としてやりとりする StrEnum
優先度や段階など、大小比較したい IntEnum
複数を同時に持てる(読み・書き・実行など) Flag
外部の関数に int のビット値として渡す IntFlag
数値と混ざって比較されると困る Enum(IntEnum にしない)

auto・unique・verify・member/nonmember の使い方

auto で値を自動採番する

from enum import Enum, StrEnum, auto

class Seq(Enum):
    A = auto()
    B = auto()
print([(m.name, m.value) for m in Seq])

class Lower(StrEnum):
    UserName = auto()
print(Lower.UserName.value)
[('A', 1), ('B', 2)]
username

auto() は Enum では 1 から順に、StrEnum ではメンバー名を小文字にした文字列を割り当てます。 UserName のような名前も username になる点は覚えておくと安心です。

値が重複するとエイリアスになる/@unique で禁止する

from enum import Enum, unique

class Shape(Enum):
    SQUARE = 2
    DIAMOND = 1
    CIRCLE = 3
    ALIAS_FOR_SQUARE = 2
print(Shape.ALIAS_FOR_SQUARE, Shape.ALIAS_FOR_SQUARE is Shape.SQUARE, list(Shape), list(Shape.__members__))

try:
    @unique
    class Mistake(Enum):
        ONE = 1
        TWO = 1
except ValueError as e:
    print("ValueError:", e)
Shape.SQUARE True [<Shape.SQUARE: 2>, <Shape.DIAMOND: 1>, <Shape.CIRCLE: 3>] ['SQUARE', 'DIAMOND', 'CIRCLE', 'ALIAS_FOR_SQUARE']
ValueError: duplicate values found in <enum 'Mistake'>: TWO -> ONE

同じ値を持つメンバーは、最初のメンバーの「別名(エイリアス)」になります。 list(Shape) には出てこず、__members__ にだけ残ります。値の書き間違いでうっかり重複させないためには @unique を付けると、定義した時点で ValueError にできます。

@verify で連番などの制約をチェックする(3.11+)

from enum import IntEnum, verify, CONTINUOUS

try:
    @verify(CONTINUOUS)
    class Level(IntEnum):
        A = 1
        B = 2
        C = 4
except ValueError as e:
    print("ValueError:", e)
ValueError: invalid enum 'Level': missing values 3
verify の引数 チェック内容
UNIQUE 値の重複がない(@unique と同じ)
CONTINUOUS 整数値に抜けがない
NAMED_FLAGS Flag の組み合わせ値が、すべて名前付きのフラグでできている

メソッド・プロパティ・タプル値・member/nonmember

Enumは普通のクラスと同じようにメソッドやプロパティを追加できます。 値をタプルにして __init__ で受け取ると、1つのメンバーに複数の属性を持たせられます。

from enum import Enum, member, nonmember

class Planet(Enum):
    MERCURY = (3.303e+23, 2.4397e6)
    EARTH = (5.976e+24, 6.37814e6)

    def __init__(self, mass, radius):
        self.mass = mass
        self.radius = radius

    @property
    def gravity(self):
        G = 6.673e-11
        return G * self.mass / (self.radius * self.radius)

print(Planet.EARTH.value, round(Planet.EARTH.gravity, 2))

class Op(Enum):
    ADD = member(lambda a, b: a + b)
    SUB = member(lambda a, b: a - b)
    note = nonmember("メモ")

    def __call__(self, *args):
        return self.value(*args)

print([m.name for m in Op], Op.ADD(2, 3), Op.note)
(5.976e+24, 6378140.0) 9.8
['ADD', 'SUB'] 5 メモ

通常、クラス内の関数(lambda を含む)はメソッドとして扱われ、メンバーになりません。 member() で包むとメンバーになり、逆に nonmember() で包んだ値はメンバーにならず、ただのクラス属性になります。

StrEnumにメソッドを足して使う(タスクの状態の例)

状態を表す StrEnum に「表示名」「次の状態」「文字列からの変換」を持たせると、状態に関する処理を1か所にまとめられます。 以降の例でもこの Status を使います。

from enum import StrEnum, auto

class Status(StrEnum):
    TODO = auto()
    DOING = auto()
    DONE = auto()

    @property
    def label(self) -> str:
        return {"todo": "未着手", "doing": "対応中", "done": "完了"}[self.value]

    def next(self) -> "Status":
        members = list(Status)
        i = members.index(self)
        return members[min(i + 1, len(members) - 1)]

    @classmethod
    def parse(cls, text: str) -> "Status":
        return cls(text.strip().lower())

print(Status.TODO.label, Status.TODO.next(), Status.DONE.next(), Status.parse(" DOING "))
未着手 doing done doing

_missing_ で値の受け取り方を広げる

from enum import Enum

class Size(Enum):
    S = 1

    @classmethod
    def _missing_(cls, value):
        if isinstance(value, str):
            for m in cls:
                if m.name == value.upper():
                    return m
        return None

print(Size("s"))
try:
    Size(5)
except ValueError as e:
    print("ValueError:", e)
Size.S
ValueError: 5 is not a valid Size

_missing_ は値が見つからなかったときに呼ばれるクラスメソッドです。名前の小文字や旧表記などを受け付けたいときに使い、該当しなければ None を返すと通常どおり ValueError になります。

match文と組み合わせる

Enumのメンバーは case Status.TODO: のように「ドット付きの名前」で書くと、値のパターンとして比較されます。 | で複数をまとめることもできます。

from enum import Enum, StrEnum, auto

class Status(StrEnum):
    TODO = auto()
    DOING = auto()
    DONE = auto()

def describe(s: Status) -> str:
    match s:
        case Status.TODO:
            return "これから着手"
        case Status.DOING | Status.DONE:
            return f"{s}のタスク"

for s in Status:
    print("match:", s, "->", describe(s))

class Color(Enum):
    RED = 1
    GREEN = 2

def f(c):
    match c:
        case Color.RED:
            return "red"
        case _:
            return "other"

print(f(Color.RED), f(1))

実行結果(Python 3.11.15):

match: todo -> これから着手
match: doing -> doingのタスク
match: done -> doneのタスク
red other

普通の Enum は 1 と等しくないため、f(1) は case _ に進みます。

mypy で「case の書き漏れ」を見つける

case _: assert_never(s) を最後に置くと、メンバーを追加して case を書き忘れたときに型チェッカーが知らせてくれます。

from enum import StrEnum, auto
from typing import assert_never

class Status(StrEnum):
    TODO = auto()
    DONE = auto()

def label(s: Status) -> str:
    match s:
        case Status.TODO:
            return "未着手"
        case _:
            assert_never(s)

mypy 1.20.2 の出力(ファイル名を label.py として実行):

label.py:13: error: Argument 1 to "assert_never" has incompatible type "Literal[Status.DONE]"; expected "Never"  [arg-type]

Status.DONE の case がないことを、実行前に指摘してくれました。 assert_never は Python 3.11 から typing に入っています。

JSON・SQLite・dataclass・Pydanticと組み合わせる

StrEnum(と IntEnum)は str・int のサブクラスなので、JSONやDBにそのまま渡せます。 普通の Enum は変換が必要です。

import json
import sqlite3
from dataclasses import dataclass, asdict
from enum import Enum, StrEnum, auto

class Status(StrEnum):
    TODO = auto()
    DOING = auto()
    DONE = auto()

class Color2(Enum):
    RED = "red"

# JSON に書く/読む
print(json.dumps({"id": 1, "status": Status.DOING}))
try:
    json.dumps({"c": Color2.RED})
except TypeError as e:
    print("TypeError:", e)
print(json.dumps({"c": Color2.RED}, default=lambda o: o.value if isinstance(o, Enum) else o))
loaded = json.loads('{"id": 1, "status": "doing"}')
print(Status(loaded["status"]), repr(Status(loaded["status"])))

# dataclass
@dataclass
class Task:
    title: str
    status: Status = Status.TODO

t = Task("備品を発注")
print(t, asdict(t), json.dumps(asdict(t), ensure_ascii=False))

# SQLite
con = sqlite3.connect(":memory:")
con.execute("create table task(title text, status text)")
con.execute("insert into task values (?, ?)", ("在庫確認", Status.DONE))
row = con.execute("select title, status from task").fetchone()
print(row, Status(row[1]))
try:
    con.execute("insert into task values (?, ?)", ("x", Color2.RED))
except Exception as e:
    print(type(e).__name__, e)

実行結果(Python 3.11.15。3.14.7でも同じ出力):

{"id": 1, "status": "doing"}
TypeError: Object of type Color2 is not JSON serializable
{"c": "red"}
doing <Status.DOING: 'doing'>
Task(title='備品を発注', status=<Status.TODO: 'todo'>) {'title': '備品を発注', 'status': <Status.TODO: 'todo'>} {"title": "備品を発注", "status": "todo"}
('在庫確認', 'done') done
ProgrammingError Error binding parameter 2: type 'Color2' is not supported
渡し先 StrEnum / IntEnum 普通の Enum
json.dumps そのまま文字列・数値になる TypeError → default= で .value に変換
SQLite(? パラメータ) そのまま保存できる ProgrammingError → .value を渡す
読み戻し Status(row[1]) で Enum に戻す Color2(row[1]) で戻す
dataclass の asdict Enumメンバーのまま入る(JSON化はそのままOK) Enumメンバーのまま入る

保存するときは「値」、読み込んだら Status(値) で Enum に戻す、という往復を決めておくと扱いやすくなります。

Pydantic v2 で検証する

from enum import StrEnum, auto
from pydantic import BaseModel, ValidationError, ConfigDict

class Status(StrEnum):
    TODO = auto()
    DOING = auto()
    DONE = auto()

class TaskIn(BaseModel):
    title: str
    status: Status

m = TaskIn(title="記事を書く", status="doing")
print(repr(m.status), m.model_dump(), m.model_dump(mode="json"), m.model_dump_json())
try:
    TaskIn(title="x", status="pending")
except ValidationError as e:
    print(e)

class TaskOut(BaseModel):
    model_config = ConfigDict(use_enum_values=True)
    status: Status

print(repr(TaskOut(status="done").status))

実行結果(Python 3.11.15、pydantic 2.13.3):

<Status.DOING: 'doing'> {'title': '記事を書く', 'status': <Status.DOING: 'doing'>} {'title': '記事を書く', 'status': 'doing'} {"title":"記事を書く","status":"doing"}
1 validation error for TaskIn
status
  Input should be 'todo', 'doing' or 'done' [type=enum, input_value='pending', input_type=str]
    For further information visit https://errors.pydantic.dev/2.13/v/enum
'done'

文字列 "doing" を渡すと自動で Status.DOING に変換され、選択肢にない "pending" は ValidationError になります。 model_dump(mode="json") は値の文字列に、use_enum_values=True を付けるとモデル内でも値の文字列で保持します。

定数クラス・Literal型・Enumの使い分け

選択肢を表す方法は主に3つあり、「型チェックでどこまで守りたいか」「実行時にメンバーを列挙したいか」で選びます。 3つを mypy でチェックした結果がこちらです。

from enum import StrEnum, auto
from typing import Final, Literal

class StatusConst:
    TODO: Final = "todo"
    DONE: Final = "done"

StatusLit = Literal["todo", "done"]

class Status(StrEnum):
    TODO = auto()
    DONE = auto()

def by_const(s: str) -> None: ...
def by_lit(s: StatusLit) -> None: ...
def by_enum(s: Status) -> None: ...

by_const("tood")
by_lit("tood")
by_enum("todo")
by_enum(Status.TODO)

mypy 1.20.2 の出力(ファイル名を choices.py として実行):

choices.py:19: error: Argument 1 to "by_lit" has incompatible type "Literal['tood']"; expected "Literal['todo', 'done']"  [arg-type]
choices.py:20: error: Argument 1 to "by_enum" has incompatible type "str"; expected "Status"  [arg-type]

定数クラスの引数は str なので、タイプミス "tood" は検出されません。 Literal は書き間違いを検出し、Enum はメンバー以外(ただの文字列)を受け付けないようにできます。

観点 定数クラス Literal 型 Enum / StrEnum
タイプミスの検出(mypy) されない される される
実行時に一覧を取る 自分で書く typing.get_args() で取れる list(Status)
メソッド・表示名を持たせる できる(別管理) できない できる
外部の文字列を検証して変換 自分で書く 自分で書く Status("todo") で ValueError
文字列のまま扱える はい はい StrEnum なら はい
書く量 少ない 最も少ない やや多い
判断の目安 おすすめ
関数の引数を2〜3個の文字列に絞りたいだけ Literal
選択肢に表示名・遷移などの振る舞いがある StrEnum(または Enum)
外部入力を受け取り、検証して変換したい StrEnum
選択肢ではない設定値(タイムアウト秒数など) Final の定数

つまずきやすいポイント

1. IntEnum は int や別の IntEnum とも等しくなる

from enum import Enum, IntEnum

class Priority(IntEnum):
    LOW = 1
    HIGH = 2

class Size(IntEnum):
    S = 1
    M = 2

print(Priority.LOW == Size.S, Priority.LOW == 1, {1: "one"}[Priority.LOW], Priority.HIGH * 10)

class P2(Enum):
    LOW = 1

print(P2.LOW == 1, P2.LOW.value == 1)
True True one 20
False True

IntEnum は int として比較されるため、意味の違う Priority.LOW と Size.S も等しくなります。 混同を避けたいときは普通の Enum を使い、値は .value で取り出します。

2. str と Enum の多重継承と StrEnum では str() が違う

from enum import Enum, StrEnum

class Old(str, Enum):
    TODO = "todo"

class New(StrEnum):
    TODO = "todo"

print(repr(str(Old.TODO)), repr(f"{Old.TODO}"), repr(str(New.TODO)), repr(f"{New.TODO}"), Old.TODO == "todo")

実行結果(3.11.15・3.14.7とも):

'Old.TODO' 'Old.TODO' 'todo' 'todo' True

class Old(str, Enum) は比較では文字列として振る舞いますが、str() や f-string では 'Old.TODO' になります。 ファイル名やURLの組み立てに使うと意図しない文字列になるので、3.11以降は StrEnum を使うと値がそのまま出ます。 3.10以前も対象にするなら .value を明示します。

3. StrEnum には文字列以外の値を書けない

from enum import StrEnum

try:
    class Bad(StrEnum):
        A = 1
except TypeError as e:
    print("TypeError:", e)
TypeError: 1 is not a string

4. Flag の組み合わせは名前がまとめて表示される

from enum import Flag, auto

class Perm(Flag):
    READ = auto()
    WRITE = auto()
    EXEC = auto()
    RW = READ | WRITE

print(list(Perm), list(Perm.__members__), Perm.RW, repr(Perm(3)), repr(Perm(0)))
try:
    Perm(8)
except ValueError as e:
    print("ValueError:", e)
print(len(Perm), Perm(7))
[<Perm.READ: 1>, <Perm.WRITE: 2>, <Perm.EXEC: 4>] ['READ', 'WRITE', 'EXEC', 'RW'] Perm.RW <Perm.RW: 3> <Perm: 0>
ValueError: <flag 'Perm'> invalid value 8
    given 0b0 1000
  allowed 0b0 0111
3 Perm.READ|WRITE|EXEC

3.11以降の Flag は、list(Perm) や len(Perm) が1ビットの基本フラグだけを数えます。 組み合わせに名前(RW)を付けておくと表示がその名前になり、名前がない組み合わせは Perm.READ|WRITE|EXEC のように | で並びます。定義にないビット(8)は Flag では ValueError、IntFlag ではそのまま保持されます。

つまずきチェックリスト

症状 原因 直し方
Color.RED == 1 が False 普通の Enum は値と等しくない .value で比べる/IntEnum にする
一覧にメンバーが足りない 値が重複してエイリアスになった @unique を付ける
f-string で Old.TODO と出る (str, Enum) の str() StrEnum にする/.value
json.dumps で TypeError 普通の Enum は JSON 化できない StrEnum にする/default=
1 in Color で TypeError 3.11 以前の仕様 3.12以降にする/.value の集合で調べる
関数をメンバーにしたのに一覧にない 関数はメソッド扱い member() で包む

よくある質問

Q. Enum の値から名前を取るにはどうしますか? A. Color(1).name で 'RED' が取れます。 逆に名前の文字列からは Color["RED"]、値は .value です。

Q. StrEnum は何バージョンから使えますか? A. Python 3.11 からです。 3.10以前では class Status(str, Enum) で近い動きになりますが、str() の結果が 'Status.TODO' になる違いがあります。

Q. Enum と Literal 型はどちらを使えばよいですか? A. 引数を数個の文字列に絞るだけなら Literal、表示名やメソッド、外部入力の検証まで持たせたいなら StrEnum が向いています。 どちらも mypy でタイプミスを検出できます。

Q. match 文で Enum を使うときの書き方は? A. case Status.TODO: のようにクラス名付きで書きます。 最後に case _: assert_never(s) を置くと、case の書き漏れを型チェッカーが知らせてくれます。

まとめ

  • Enum は「決まった選択肢」に名前を付ける型。Color(1) で値から、Color["RED"] で名前から取り出せる
  • JSON・DB・APIとやりとりするなら StrEnum(3.11+)、大小比較なら IntEnum、組み合わせなら Flag
  • auto() は Enum では連番、StrEnum では名前の小文字。値の重複は @unique で防ぐ
  • メソッド・プロパティ・_missing_ を足すと、状態に関する処理を1か所にまとめられる
  • match 文は case Status.TODO: と書き、assert_never で書き漏れを mypy に検出させる
  • 引数を絞るだけなら Literal、振る舞いや入力検証まで持たせるなら Enum と使い分ける

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Python Enumの使い方|StrEnum・auto・match文まで一覧解説」

株式会社RJCでは、PythonのEnumのような型の使い方を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?