PythonのEnumを用いて複数ステータスをビット演算で管理する thumbnail

PythonのEnumを用いて複数ステータスをビット演算で管理する

2025-02-25

概要

Python における Enum(列挙型)は複数の定数を体系的に管理するための機能です。本記事では、この Enum を利用して複数のステータスを効率的にビット演算で管理する方法について詳しく解説します。

Enum とビットフラグとは

Python の標準モジュールであるenumには主に次の 4 つのクラスがあります。ここで、Enum や IntEnum は基本的な定数管理に用いられ、IntEnum は整数との比較が可能なため、排他的な状態管理(状態は基本的に一つ)に適しています。一方、Flag や IntFlag はビット演算により複数のステータス(フラグ)を同時に管理するために設計され、IntFlag は整数との互換性を持ちながら、複数のフラグを組み合わせる用途に向いています。

クラス名 説明 メンバ間の演算 整数との互換性 用途
Enum 通常の列挙型。単一の状態管理に利用 不可 無し 定数管理(状態は一つ)
IntEnum Enum の整数型バージョン。整数値との比較が可能 不可 有り 状態管理(排他的な状態)
Flag ビット演算を利用したフラグ型。複数フラグを組み合わせ可能 可 無し 複数のフラグ管理
IntFlag Flag の整数型バージョン。整数値としての演算・比較が可能 可 有り 複数のフラグ管理

Enum

通常の Enum は定数値を列挙します。演算は行えません。

from enum import Enum

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

print(Color.RED)  # Color.RED

IntEnum

IntEnum は整数としても扱える Enum です。

from enum import IntEnum

class Status(IntEnum):
    SUCCESS = 0
    FAILURE = 1

print(Status.SUCCESS == 0)  # True

Flag

ビット単位の演算を行えますが、整数値との直接的な比較はできません。

from enum import Flag, auto

class Permission(Flag):
    READ = auto()
    WRITE = auto()

perm = Permission.READ | Permission.WRITE
print(perm)  # Permission.READ|WRITE

IntFlag

Flag の整数互換バージョンで、整数値としての演算や比較が可能です。

from enum import IntFlag, auto

class Permission(IntFlag):
    READ = auto()
    WRITE = auto()

perm = Permission.READ | Permission.WRITE
print(perm == 3)  # True

本記事では主にIntFlagを利用したビットフラグの管理方法を解説します。

複数ステータスの設定方法

複数のステータスを設定するにはビット単位の論理和(OR)演算子|を用います。

status = Permission.READ | Permission.WRITE
print(status)  # Permission.READ|WRITE

特定ステータスの確認方法

設定されたステータスを確認するには、論理積(AND)演算子&を用います。

if status & Permission.READ:
    print("READ可能")

ステータスの無効化方法

特定のステータスを無効化するには、論理否定(NOT)演算子~と論理積(AND)演算子&を組み合わせて使用します。

status &= ~Permission.WRITE
print(status)  # Permission.READ

ステータスの切り替え方法

フラグの状態を切り替えるには排他的論理和(XOR)演算子^を用います。

status ^= Permission.WRITE
print(status)  # Permission.READ|WRITE

実践的な例

以下に実践的な使用例を示します。

from enum import IntFlag, auto

class Permission(IntFlag):
    READ = auto()
    WRITE = auto()
    EXECUTE = auto()
    DELETE = auto()

user_permission = Permission.READ | Permission.WRITE

if user_permission & Permission.WRITE:
    print("書き込み権限あり")

user_permission |= Permission.EXECUTE
print(user_permission)

user_permission &= ~Permission.WRITE
print(user_permission)

ビットフラグ管理のメリット

  • メモリ効率が良い(複数の状態を 1 つの整数で管理可能)
  • 状態チェックや変更が高速かつ簡単
  • 拡張が容易

まとめ

Python のIntFlagを用いたビットフラグ管理は、多数のステータスをシンプルかつ効率的に扱うための強力な手法です。ビット演算を用いることで、状態の設定、確認、切り替え、削除が非常に簡潔に表現できます。実務で広く利用されるテクニックであり、覚えておくと役立つでしょう。