enum【列挙型モジュール】3.43.5~3.7 / 3.113.12
EnumType【列挙型メタクラス】3.113.12
Enum【列挙型 (基本クラス)】3.6~3.7 / 3.113.12
IntEnum【列挙型 (整数)】3.11
Flag【列挙型 (ビットフラグ)】3.63.11
IntFlag【列挙型 (整数ビットフラグ)】3.63.11
StrEnum【列挙型 (文字列)】3.11

メモ

概要

使用方法

  • 各列挙型のサブクラスとして使用 (但し、一般的なクラスとは相違)〔詳細は各列挙型参照〕
  • メンバ名は定数として全て大文字推奨 3.6
    • 先頭と末尾が 1 個のアンダースコアのメンバ名は定義不可
  • pickle 化・unpickle 化 可能
  • 継承〔
    • 列挙子メンバが未定義の場合のみ、継承可
  • 独自列挙型〔
    • 以下の順でサブクラス指定可
      • 複数の object ベースのミックスインクラス
      • 最大 1 つの具象データ型
      • 1 つの基本 enum クラス
    • メンバ値はデータ型のコンストラクタに引き渡し

モジュール定義

  • モジュールは下記を定義
    基本クラス・メタクラス備考
    EnumType 3.113.12
    (別名:EnumMeta3.43.5 )
    Enum【列挙型 (基本クラス)】のメタクラス
    Enum 3.6~3.7 / 3.113.12 列挙型 (基本クラス)
    全てのenum 列挙型の基本クラス (整数以外も可)
    ReprEnum 3.11 mix-inのstr【文字列変換】保持の為、以下で使用
    IntEnum【列挙型 (整数)】IntFlag【列挙型 (整数ビットフラグ)】StrEnum【列挙型 (文字列)】
    列挙型クラス備考
    IntEnum 3.11 列挙型 (整数)
    (整数値との比較可:既存システムとの互換等で使用)
    Flag 3.63.11 列挙型 (ビットフラグ)
    注:str【文字列型】等を定義可、但し他のメンバもビット演算不可
    IntFlag 3.63.11 列挙型 (整数ビットフラグ)
    (整数値との比較可:既存システムとの互換等で使用)
    StrEnum 3.11 列挙型 (文字列)
    その他クラス備考
    auto 3.63.11.1 値の自動取得〔例:各列挙型参照〕
    下記でオーバーライド可 (メンバ定義の前に定義)3.6
    _generate_next_value_(name, start, count, last_values)
    戻り値設定値
    name定義名
    start開始値
    count定義数
    last_values定義メンバ

    ※ 数値のデフォルト開始番号:C++等の 0 ではなく 1
    ※ 最上位にあれば単独でなくても可 (例:括弧のないタプル) 3.11.1
    ※ 互換性のない値の指定 (デフォルトに逆行) 3.12 例外3.13
    EnumCheck 3.11 制約オプション定数
    (@verify【制約検証 デコレータ】のオプション定義)
    FlagBoundary 3.11 範囲外値の制御 (FlagIntFlag 用)
    (boundary= で指定)
    指定値は EnumCheck【制約オプション定数】で定義
    STRICT:範囲外の値はValueError 例外 (Flag【列挙型 (ビットフラグ)】のデフォルト)
    ・CONFORM:無効ビットフラグ値削除
    ・EJECT:範囲外の値は int とみなす
    KEEP:範囲外の値は保持し列挙型のまま (IntFlag【列挙型 (整数ビットフラグ)】のデフォルト)
    関連:
    Enum._missing_(cls)【未検索処理】
    EnumType.__call__(cls)【値アクセス】enumtype(メンバ値)
    メソッド・デコレータ備考
    @global_enum 3.11 グローバル指定デコレータ〔
    (メンバはモジュール属性)
    @member 3.11
    member()3.11
    メンバ指定〔
    @nonmember 3.11
    nonmember()3.11
    非メンバ指定〔
    @property 3.11 プロパティ (メンバと同一名も可)〔
    show_flag_values(value)3.11 ユーティリティ関数:ビットフラグリスト〔例:各列挙型参照〕
    valueに含まれる全フラグ (2のべき乗)のリスト
    from enum import show_flag_values
    
    print(show_flag_values(2))  # 出力:[2]
    print(show_flag_values(7))  # 出力:[1, 2, 4]
    
    @unique ユニーク デコレータ〔例:各列挙型参照〕
    同じ値の別名定義不可 (ValueError 例外)
    @verify(オプション) 3.11 制約検証 デコレータ〔例:各列挙型参照〕
    オプション制約オプション (検証失敗:ValueError 例外)
    ・UNIQUE:ユニーク (同じ値の別名定義不可)
    ・CONTINUOUS:連続値で欠損値不可 (EnumIntEnum で有効)
    ・NAMED_FLAGS:複数ビットの組み合わせは、単独ビットの定義が必要 (FlagIntFlag で有効)

例:継承独自列挙型

from enum import Enum

# 継承
class EnumParent(Enum):
    # MEM_X = 9  # 例外
    def print_details(self):
        print(self, self.name, self.value, sep=' / ')

class EnumChild(EnumParent):
    MEM_A = 1
    MEM_B = 2

for mem in EnumChild:
    mem.print_details()
# 出力
# MyEnum.MEM_A / MEM_A / 1
# MyEnum.MEM_B / MEM_B / 2

# 独自列挙型
class MixinUser:
    def print_details(self):
        print(self, self.name, self.value, sep=' / ')

class EnumUser(MixinUser, int, Enum):
    MEM_A = 1
    MEM_B = '10', 16  # 16進数

for mem in EnumUser:
    mem.print_details()
# 出力
# EnumUser.MEM_A / MEM_A / 1
# EnumUser.MEM_B / MEM_B / 16

例:@global_enum【グローバル指定デコレータ】

from enum import Enum, IntEnum, global_enum

@global_enum
class ColorEnum(Enum):
    RED = 0xFF0000
    GREEN = 0x00FF00
    BLUE = 0x0000FF

print(RED)
# 出力:RED
print(RED.name)
# 出力:RED
print(f'{RED.value:#08x}')
# 出力:0xff0000

@global_enum
class IntColorEnum(IntEnum):
    COLOR_RED = 0xFF0000
    COLOR_GREEN = 0x00FF00
    COLOR_BLUE = 0x0000FF

print(f'{COLOR_GREEN:#08x}')
# 出力:0x00ff00
print(COLOR_GREEN.name)
# 出力:COLOR_GREEN
print(f'{COLOR_GREEN.value:#08x}')
# 出力:0x00ff00

例:
@member・member【メンバ指定】
@nonmember・nonmember【非メンバ指定】

from enum import Enum, member, nonmember

class MemberEnum(Enum):
    MEM_1 = 1
    MEM_2 = member(2)
    MEM_3 = nonmember(3)
    MEM_4 = 4

    @staticmethod
    def method_5():
        return 5

    @member
    @staticmethod
    def method_6():
        return 6

    @nonmember
    @staticmethod
    def method_7():
        return 7

    class NestedClassA():
        pass
    # DeprecationWarning: In 3.13 classes created inside an enum will not become a member.

    @member
    class NestedClassB():
        pass

    @nonmember
    class NestedClassC():
        pass

print(len(MemberEnum))
# 出力:6
for mem in MemberEnum:
    print(mem)
# 出力
# MemberEnum.MEM_1
# MemberEnum.MEM_2
# MemberEnum.MEM_4
# MemberEnum.method_6
# MemberEnum.NestedClassA
# MemberEnum.NestedClassB

# MEM_1
print(MemberEnum.MEM_1)
# 出力:MemberEnum.MEM_1
print(MemberEnum.MEM_1.name)
# 出力:MEM_1
print(MemberEnum.MEM_1.value)
# 出力:1

# MEM_2
print(MemberEnum.MEM_2)
# 出力:MemberEnum.MEM_2
print(MemberEnum.MEM_2.name)
# 出力:MEM_2
print(MemberEnum.MEM_2.value)
# 出力:2

# MEM_3 (非メンバ)
print(MemberEnum.MEM_3)
# 出力:3

# MEM_4
print(MemberEnum.MEM_4)
# 出力:MemberEnum.MEM_4
print(MemberEnum.MEM_4.name)
# 出力:MEM_4
print(MemberEnum.MEM_4.value)
# 出力:4

# method_5 (非メンバ)
print(MemberEnum.method_5)
# 出力:<function ~.<locals>.MemberEnum.method_5 at 0x~>

# method_6
print(MemberEnum.method_6)
# 出力:MemberEnum.method_6
print(MemberEnum.method_6.name)
# 出力:method_6
print(MemberEnum.method_6.value)
# 出力:<function ~.<locals>.MemberEnum.method_6 at 0x~>

# method_7 (非メンバ)
print(MemberEnum.method_7)
# 出力:<function ~.<locals>.MemberEnum.method_7 at 0x~>

# NestedClassA
print(MemberEnum.NestedClassA)
# 出力:MemberEnum.NestedClassA
print(MemberEnum.NestedClassA.name)
# 出力:NestedClassA
print(MemberEnum.NestedClassA.value)
# 出力:<class '~.<locals>.MemberEnum.NestedClassA'>

# NestedClassB
print(MemberEnum.NestedClassB)
# 出力:MemberEnum.NestedClassB
print(MemberEnum.NestedClassB.name)
# 出力:NestedClassB
print(MemberEnum.NestedClassB.value)
# 出力:<class '~.<locals>.MemberEnum.NestedClassB'>
print(MemberEnum['NestedClassB'])
# 出力:MemberEnum.NestedClassB

# NestedClassC (非メンバ)
print(MemberEnum.NestedClassC)
# 出力:<class '~.<locals>.MemberEnum.NestedClassC'>

例:@property【プロパティ】

from enum import Enum

class ColorEnum(Enum):
    RED = 0xFF0000
    GREEN = 0x00FF00
    BLUE = 0x0000FF
    @property
    def rgb(self):
        r = (self.value & 0xFF0000) >> 16
        g = (self.value & 0x00FF00) >> 8
        b = self.value & 0x0000FF
        return (r, g, b)

print(ColorEnum.RED.rgb)
# 出力:(255, 0, 0)
print(ColorEnum.GREEN.rgb)
# 出力:(0, 255, 0)
print(ColorEnum.BLUE.rgb)
# 出力:(0, 0, 255)

EnumType【列挙型メタクラス】3.113.12
(別名:EnumMeta 3.43.5 )

メモ

概要

メソッド

メソッド備考
__call__(
    cls (列挙型),
    value,
    names=None,
    *,
    module=None,
    qualname=None,
    type=None,
    start3.5 =1,
    boundary3.11 =None)
関数呼び出し作成〔
列挙型
value列挙名
namesメンバ名 / メンバ値 (以下で指定)
・メンバ名の文字列 (スペース区切り)
・メンバ名の文字列 (カンマ区切り)
・メンバ名の list【リスト】
・メンバ名とメンバ値の tuple【タプル】list【リスト】
・メンバ名とメンバ値の dict【辞書】
以下、キーワード引数
moduleモジュール名
qualnameモジュール場所
type複合データ型
start3.5開始値 (auto【値自動取得】で使用)
boundary3.11Flag制御 範囲外の値処理 (FlagIntFlagで使用)
__call__(
    cls (列挙型),
    value)
値アクセス〔例:各列挙型参照〕
enumtype(メンバ値)
メンバ (列挙子)
value:検索メンバ値
関連:
Enum._missing_(cls)【未検索処理】
FlagBoundary【範囲外値の制御】
__contains__( 3.12
    cls (列挙型),
    member)
所属判定 (列挙型)〔例:各列挙型参照〕
メンバ | メンバ値 in 列挙型
メンバ | メンバ値 not in 列挙型
所属有無 (True:所属あり / False:所属なし)
memberメンバ / メンバ値3.12
関連:Flag:__contains__(self)【所属判定 (列挙子:ビットフラグ)】
__dir__(cls (列挙型)) 名前リスト・属性リスト
参考:組み込み関数 dir【名前リスト・属性リスト】
__getattr__(cls, name) 3.12
__getitem__(
    cls (列挙型),
    name)
名前アクセス〔例:各列挙型参照〕
enumtype['メンバ名']
メンバ (列挙子)
name検索メンバ名
KeyError 例外該当なし
__iter__(cls (列挙型)) イテレータ (列挙型)〔例:各列挙型参照〕
・別名は対象外
FlagIntFlag のビットなし・複数ビットも対象外 3.11
関連:Flag.__iter__(self)【イテレータ (列挙子:ビットフラグ)】
__len__(cls (列挙型)) メンバ数〔例:各列挙型参照〕
len(列挙型)
・別名は対象外
FlagIntFlag のビットなし・複数ビットも対象外 3.11
関連:Flag.__len__(self)【ビットフラグ数】
__reversed__(cls (列挙型)) 逆順〔例:各列挙型参照〕
参考:組み込み関数 reversed【逆順】

Enum【列挙型 (基本クラス)】3.6~3.7 / 3.113.12

メモ

属性・メソッド

属性備考
nameメンバ名〔例:各列挙型参照〕
valueメンバ値〔例:各列挙型参照〕
_ignore_3.7 無視リスト (list | str)〔
メンバの動的作成可
メソッド備考
__dir__(self (メンバ)) 名前リスト・属性リスト
参考:組み込み関数 dir【名前リスト・属性リスト】
_generate_next_value_(name, start, count, last_values) 3.6 auto カスタマイズ〔例:各列挙型参照〕
詳細は、auto【値自動取得】参照
__init_subclass__(cls (列挙型), **kwds (キーワード引数)) クラス継承処理
呼出し前にメンバ定義 3.11
_missing_( 3.6
    cls (列挙型),
    value (検索メンバ値))
メンバ値が見つからない場合の処理 (デフォルト:なし / オーバーライド可)〔例:各列挙型参照〕
代替メンバ
関連:
EnumType.__call__(cls)【値アクセス】enumtype(メンバ値)
FlagBoundary【範囲外値の制御】
__repr__(self (メンバ)) 3.12 印字可能文字列変換 (オーバーライド可)
@dataclass【データクラス】のサポート (データクラス名非表示) 3.12
参考:組み込み関数 repr【印字可能文字列変換】
__str__(self (メンバ)) 文字列変換 (オーバーライド可)〔例:各列挙型参照〕
参考:str【文字列変換】
__format__(self (メンバ)) 書式フォーマット〔例:各列挙型参照〕
format【書式化】・f-string【フォーマット済み文字列リテラル】
Enum.__str__() と同じ結果 3.11

概要

使用方法

値の自動定義

制約指定

メンバ参照

所属・比較

その他

関連


Enum 例:関数呼び出し作成
EnumType.__call__【関数呼び出し作成】

from enum import Enum

# 参考:サブクラス化
class EnumSubClass(Enum):
    LEFT = 1
    CENTER = 2
    RIGHT = 3

for mem in EnumSubClass:
    print(mem, mem.name, mem.value, sep=' / ')
# 出力
# EnumSubClass.LEFT / LEFT / 1
# EnumSubClass.CENTER / CENTER / 2
# EnumSubClass.RIGHT / RIGHT / 3

# 関数呼び出し作成 (文字列:スペース区切り)
EnumStr1 = Enum('EnumStr1', 'LEFT CENTER RIGHT')
for mem in EnumStr1:
    print(mem, mem.name, mem.value, sep=' / ')
# 出力
# EnumStr1.LEFT / LEFT / 1
# EnumStr1.CENTER / CENTER / 2
# EnumStr1.RIGHT / RIGHT / 3

# 関数呼び出し作成 (文字列:カンマ区切り)
EnumStr2 = Enum('EnumStr2', 'LEFT, CENTER, RIGHT')
for mem in EnumStr2:
    print(mem, mem.name, mem.value, sep=' / ')
# 出力
# EnumStr2.LEFT / LEFT / 1
# EnumStr2.CENTER / CENTER / 2
# EnumStr2.RIGHT / RIGHT / 3

# 関数呼び出し作成 (リスト)
EnumList = Enum('EnumList', ['LEFT', 'CENTER', 'RIGHT'])
for mem in EnumList:
    print(mem, mem.name, mem.value, sep=' / ')
# 出力
# EnumList.LEFT / LEFT / 1
# EnumList.CENTER / CENTER / 2
# EnumList.RIGHT / RIGHT / 3

# 関数呼び出し作成 (Tuple:メンバ値指定)
EnumTuple = Enum('EnumTuple', [('LEFT', 11), ('CENTER', 12), ('RIGHT', 13)])
for mem in EnumTuple:
    print(mem, mem.name, mem.value, sep=' / ')
# 出力
# EnumTuple.LEFT / LEFT / 11
# EnumTuple.CENTER / CENTER / 12
# EnumTuple.RIGHT / RIGHT / 13

# 関数呼び出し作成 (Dict:メンバ値指定)
EnumDict = Enum('EnumDict', {'LEFT':21, 'CENTER':22, 'RIGHT':23})
for mem in EnumDict:
    print(mem, mem.name, mem.value, sep=' / ')
# 出力
# EnumDict.LEFT / LEFT / 21
# EnumDict.CENTER / CENTER / 22
# EnumDict.RIGHT / RIGHT / 23

# 関数呼び出し作成 (開始値指定)
EnumStart = Enum('EnumStart', ['LEFT', 'CENTER', 'RIGHT'], start=101)
for mem in EnumStart:
    print(mem, mem.name, mem.value, sep=' / ')
# 出力
# EnumStart.LEFT / LEFT / 101
# EnumStart.CENTER / CENTER / 102
# EnumStart.RIGHT / RIGHT / 103

Enum 例:使用方法

from enum import Enum, unique

@unique
class EnumUnique(Enum):
    MEM_A = 1
    MEM_B = 'Mem_B'
    MEM_C = ['Mem_C_1', 'Mem_C_2', 'Mem_C_3']
    # MEM_X = MEM_A  # 別名:ValueError 例外
    # ValueError: duplicate values found in <enum 'EnumUnique'>: MEM_X -> MEM_A

    # Enum.name【メンバ名】
    # Enum.value【メンバ値】
    def print_details(self):
        print(self, self.name, self.value, sep=' / ')


# メンバ参照
for mem in EnumUnique:
    mem.print_details()
# 出力
# EnumUnique.MEM_A / MEM_A / 1
# EnumUnique.MEM_B / MEM_B / Mem_B
# EnumUnique.MEM_C / MEM_C / ['Mem_C_1', 'Mem_C_2', 'Mem_C_3']

Enum 例:メンバ動的作成

from enum import Enum

# _ignore_【無視リスト】
class EnumA(Enum):
    _ignore_ = 'MEM_B'
    MEM_A = 1
    MEM_B = 2
    MEM_C = 3

print(len(EnumA))
# 出力:2
for mem in EnumA:
    print(mem, mem.name, mem.value, sep=' / ')
# 出力
# EnumA.MEM_A / MEM_A / 1
# EnumA.MEM_C / MEM_C / 3

# メンバ動的作成 (1/2)
class EnumB(Enum):
    # _ignore_ = 'EnumB i'  # 文字列形式
    _ignore_ = ['EnumB', 'i']  # リスト形式
    EnumB = vars()
    for i in range(1, 6):
        EnumB[f'MEM_{i}'] = i

print(len(EnumB))
# 出力:5
for mem in EnumB:
    print(mem, mem.name, mem.value, sep=' / ')
# 出力
# EnumB.MEM_1 / MEM_1 / 1
# EnumB.MEM_2 / MEM_2 / 2
# EnumB.MEM_3 / MEM_3 / 3
# EnumB.MEM_4 / MEM_4 / 4
# EnumB.MEM_5 / MEM_5 / 5

# メンバ動的作成 (2/2)
class EnumC(Enum):
    # _ignore_ = 'EnumC i j'  # 文字列形式
    _ignore_ = ['EnumC', 'i', 'j']  # リスト形式
    EnumC = vars()
    for i in range(1, 4):
        for j in range(1, 4):
            EnumC[f'MEM_{i}_{j}'] = i * 10 + j

print(len(EnumC))
# 出力:9
for mem in EnumC:
    print(mem, mem.name, mem.value, sep=' / ')
# 出力
# EnumC.MEM_1_1 / MEM_1_1 / 11
# EnumC.MEM_1_2 / MEM_1_2 / 12
# EnumC.MEM_1_3 / MEM_1_3 / 13
# EnumC.MEM_2_1 / MEM_2_1 / 21
# EnumC.MEM_2_2 / MEM_2_2 / 22
# EnumC.MEM_2_3 / MEM_2_3 / 23
# EnumC.MEM_3_1 / MEM_3_1 / 31
# EnumC.MEM_3_2 / MEM_3_2 / 32
# EnumC.MEM_3_3 / MEM_3_3 / 33

Enum 例:値の自動定義

from enum import Enum, auto

# auto【値自動取得】
class EnumAuto(Enum):
    MEM_A = auto()
    MEM_B = auto()
    MEM_X = 101
    MEM_Y = auto()

    def print_details(self):
        print(self, self.name, self.value, sep=' / ')


# メンバ参照
for mem in EnumAuto:
    mem.print_details()
# 出力
# EnumAuto.MEM_A / MEM_A / 1
# EnumAuto.MEM_B / MEM_B / 2
# EnumAuto.MEM_X / MEM_X / 101
# EnumAuto.MEM_Y / MEM_Y / 102

# auto カスタマイズ
class EnumAutoUser(Enum):
    # Enum._generate_next_value_【auto カスタマイズ】
    @staticmethod
    def _generate_next_value_(name, start, count, last_values):
        print(f'{name=}, {start=}, {count=}, {last_values=}')
        return (count + 1) * 10
    MEM_A = auto()
    MEM_B = auto()
    MEM_C = auto()

    def print_details(self):
        print(self, self.name, self.value, sep=' / ')
# 出力
# name='MEM_A', start=1, count=0, last_values=[]
# name='MEM_B', start=1, count=1, last_values=[10]
# name='MEM_C', start=1, count=2, last_values=[10, 20]


# メンバ参照
for mem in EnumAutoUser:
    mem.print_details()
# 出力
# EnumAutoUser.MEM_A / MEM_A / 10
# EnumAutoUser.MEM_B / MEM_B / 20
# EnumAutoUser.MEM_C / MEM_C / 30

# 最上位指定 [3.11.1]
class EnumTuple(Enum):
    MEM_A = auto(), auto(), auto()
    MEM_B = auto(), auto(), auto()
    MEM_C = auto(), auto(), auto()

    def print_details(self):
        print(self, self.name, self.value, sep=' / ')


for mem in EnumTuple:
    mem.print_details()
# 出力
# EnumTuple.MEM_1 / MEM_1 / (1, 2, 3)
# EnumTuple.MEM_2 / MEM_2 / (4, 5, 6)
# EnumTuple.MEM_3 / MEM_3 / (7, 8, 9)

# 互換性なし
class EnumAutoWarn(Enum):
    MEM_A = auto()
    MEM_B = 10
    MEM_C = auto()
    MEM_D = 5  # 互換性のない値
    MEM_E = auto()  # 警告

    def print_details(self):
        print(self, self.name, self.value, sep=' / ')
# DeprecationWarning: In 3.13 ~


for mem in EnumAutoWarn:
    mem.print_details()
# 出力
# EnumAutoWarn.MEM_A / MEM_A / 1
# EnumAutoWarn.MEM_B / MEM_B / 10
# EnumAutoWarn.MEM_C / MEM_C / 11
# EnumAutoWarn.MEM_D / MEM_D / 5
# EnumAutoWarn.MEM_E / MEM_E / 12

Enum 例:制約指定

from enum import Enum, unique, verify, UNIQUE, CONTINUOUS

# 別名有効 (デフォルト)
class EnumDefault(Enum):
    MEM_A = 1
    MEM_B = 2
    MEM_C = 3
    MEM_X = MEM_A  # 別名

# @unique【一意値】
@unique
class EnumUniqueA(Enum):
    MEM_A = 1
    MEM_B = 2
    MEM_C = 3
    # MEM_X = MEM_A  # 別名:例外
    # ValueError: duplicate values found in <enum 'EnumUniqueA'>: MEM_X -> MEM_A

# @verify(UNIQUE)【一意値】
@verify(UNIQUE)
class EnumUniqueB(Enum):
    MEM_A = 1
    MEM_B = 2
    MEM_C = 3
    # MEM_X = MEM_A  # 別名:例外
    # ValueError: aliases found in <enum 'EnumUniqueB'>: MEM_X -> MEM_A

# @verify(CONTINUOUS)【連続値】
@verify(CONTINUOUS)
class EnumContinuous(Enum):
    MEM_A = 1
    MEM_B = 2
    MEM_C = 3
    # MEM_X = 7  # 不連続:例外
    # ValueError: invalid enum 'EnumContinuous': missing values 4, 5, 6

# _order_【定義順】
class EnumOrder(Enum):
    # _order_ = 'MEM_C MEM_B MEM_A'  # 例外
    MEM_A = 1
    MEM_B = 2
    MEM_C = 3
# TypeError: member order does not match _order_:
#   ['MEM_A', 'MEM_B', 'MEM_C']
#   ['MEM_C', 'MEM_B', 'MEM_A']

Enum 例:メンバ参照

from enum import Enum

class EnumBasic(Enum):
    MEM_A = 1
    MEM_B = 2
    MEM_C = 3
    MEM_X = MEM_A  # 別名

# EnumType.__len__(cls)【メンバ数】len(列挙型)
print(len(EnumBasic))
# 出力:3

# EnumType.__iter__(cls)【イテレータ (列挙型)】
# EnumType.__reversed__(cls)【逆順】
for mem in EnumBasic:
    print(mem)
# 出力
# EnumBasic.MEM_A
# EnumBasic.MEM_B
# EnumBasic.MEM_C
for mem in reversed(EnumBasic):
    print(mem)
# 出力
# EnumBasic.MEM_C
# EnumBasic.MEM_B
# EnumBasic.MEM_A
print(list(EnumBasic))
# 出力:[<EnumBasic.MEM_A: 1>, <EnumBasic.MEM_B: 2>, <EnumBasic.MEM_C: 3>]
print(list(reversed(EnumBasic)))
# 出力:[<EnumBasic.MEM_C: 3>, <EnumBasic.MEM_B: 2>, <EnumBasic.MEM_A: 1>]
print([mem for mem in EnumBasic])
# 出力:[<EnumBasic.MEM_A: 1>, <EnumBasic.MEM_B: 2>, <EnumBasic.MEM_C: 3>]
print([mem.name for mem in EnumBasic])
# 出力:['MEM_A', 'MEM_B', 'MEM_C']
print([mem.value for mem in EnumBasic])
# 出力:[1, 2, 3]

# __members__【全メンバ列挙】
for name, mem in EnumBasic.__members__.items():
    print(name, mem, sep=' / ')
# 出力:
# MEM_A / EnumBasic.MEM_A
# MEM_B / EnumBasic.MEM_B
# MEM_C / EnumBasic.MEM_C
# MEM_X / EnumBasic.MEM_A

# 別名
alias = [name for name, mem in EnumBasic.__members__.items() if mem.name != name]
print(alias)
# 出力:['MEM_X']

# EnumType.__getitem__(cls)【名前アクセス】enumtype['メンバ名']
lst = ['MEM_A', 'MEM_B', 'MEM_C', 'MEM_X', 'MEM_XYZ']
for name in lst:
    print(name, EnumBasic[name], sep=' / ')
# 出力
# MEM_A / EnumBasic.MEM_A
# MEM_B / EnumBasic.MEM_B
# MEM_C / EnumBasic.MEM_C
# MEM_X / EnumBasic.MEM_A
# 例外:KeyError: 'MEM_XYZ'

# EnumType.__call__(cls)【値アクセス】enumtype(メンバ値)
lst = [1, 2, 3, 99]
for value in lst:
    print(f'{value} / ', end='')
    print(EnumBasic(value))
# 出力
# 1 / EnumBasic.MEM_A
# 2 / EnumBasic.MEM_B
# 3 / EnumBasic.MEM_C
# 99 /
# 例外:ValueError: 99 is not a valid ~

# Enum._missing_(cls)【未検索処理】
class EnumMissing(Enum):
    MEM_ZERO = 0
    MEM_A = 1

    @classmethod
    def _missing_(cls, value):
        print(f'_missing_({cls}, {value})')
        return cls.MEM_ZERO

print(EnumMissing(0))
# 出力:EnumMissing.MEM_ZERO
print(EnumMissing(1))
# 出力:EnumMissing.MEM_A
print(EnumMissing(99))
# 出力
# _missing_(<enum 'EnumMissing'>, 99)
# EnumMissing.MEM_ZERO

Enum 例:所属・比較

from enum import Enum

class EnumBasic(Enum):
    MEM_A = 1
    MEM_B = 2
    MEM_C = 3
    MEM_X = MEM_A  # 別名


# EnumType.__contains__(cls)【所属判定 (列挙型)】(メンバ | メンバ値) in 列挙型
print(EnumBasic.MEM_A in EnumBasic)
# 出力:True
print(EnumBasic.MEM_B in EnumBasic)
# 出力:True
print(EnumBasic.MEM_C in EnumBasic)
# 出力:True
print(EnumBasic.MEM_X in EnumBasic)
# 出力:True
print(1 in EnumBasic)
# 出力:True
print(2 in EnumBasic)
# 出力:True
print(3 in EnumBasic)
# 出力:True
print(9 in EnumBasic)
# 出力:False
print(9 not in EnumBasic)
# 出力:True

# is・is not【同一性比較】
class EnumCheck(Enum):
    MEM_A = 1

print(EnumBasic.MEM_A is EnumBasic.MEM_A)
# 出力:True
print(EnumBasic.MEM_A is EnumBasic.MEM_X)
# 出力:True
print(EnumBasic.MEM_A is not EnumBasic.MEM_B)
# 出力:True
print(EnumBasic.MEM_A is not EnumCheck.MEM_A)
# 出力:True

# ==・!=【等価比較】
print(EnumBasic.MEM_A == EnumBasic.MEM_A)
# 出力:True
print(EnumBasic.MEM_A == EnumBasic.MEM_X)
# 出力:True
print(EnumBasic.MEM_A != EnumBasic.MEM_B)
# 出力:True
print(EnumBasic.MEM_A != EnumCheck.MEM_A)
# 出力:True
print(EnumBasic.MEM_A == 1)
# 出力:False

# 大小比較
# print(EnumBasic.MEM_A < EnumBasic.MEM_B < EnumBasic.MEM_C)  # 例外
# TypeError: '<' not supported between instances of 'EnumBasic' and 'EnumBasic'
print(EnumBasic.MEM_A.value < EnumBasic.MEM_B.value < EnumBasic.MEM_C.value)
# 出力:True

IntEnum【列挙型 (整数)】3.11

メモ

概要

使用方法

値の自動定義

制約指定

互換性

  • 整数値からの置換が容易になるように、以下の仕様
    • __str__:メンバ値 (整数値) 3.11
    • __format__:メンバ値 (整数値)
  • 型判定
    • isinstance【インスタンス判定】:int【整数型】と判定されるので問題なし
    • type【型クラス】:enum【列挙型】と判定されるので、int【整数型】に変換が必要

メンバ参照

所属・演算・比較

  • 所属
  • 演算
    • 整数演算可 (結果:列挙型ではない)
  • 比較
    • is・is not:同一性比較
    • ==・!=:等価比較 (非列挙型の値とは不等)
    • >等:大小比較不可 (値にして比較)

その他

関連


IntEnum 例:使用方法

from enum import IntEnum, unique

@unique
class IntEnumUnique(IntEnum):
    MEM_A = 1
    MEM_B = 2
    MEM_C = 3
    MEM_D = '100', 2  # 2進数
    MEM_E = '10', 8   # 8進数
    MEM_F = '10', 16  # 16進数
    # MEM_X = MEM_A  # 別名:ValueError 例外
    # ValueError: duplicate values found in <enum 'IntEnumUnique'>: MEM_X -> MEM_A

    # Enum.name【メンバ名】
    # Enum.value【メンバ値】
    def print_details(self):
        print(self, self.name, self.value, sep=' / ')


# メンバ参照
for mem in IntEnumUnique:
    mem.print_details()
# 出力
# [~3.10]
# IntEnumUnique.MEM_A / MEM_A / 1
# IntEnumUnique.MEM_B / MEM_B / 2
# IntEnumUnique.MEM_C / MEM_C / 3
# IntEnumUnique.MEM_D / MEM_D / 4
# IntEnumUnique.MEM_E / MEM_E / 8
# IntEnumUnique.MEM_F / MEM_F / 16
# [3.11~]
# 1 / MEM_A / 1
# 2 / MEM_B / 2
# 3 / MEM_C / 3
# 4 / MEM_D / 4
# 8 / MEM_E / 8
# 16 / MEM_F / 16

IntEnum 例:互換性

from enum import Enum, IntEnum

# intとEnum 継承
class IntEnumUser(int, Enum):
    MEM_A = 1
    MEM_B = 2
    MEM_C = 3

# __str__
print(IntEnumUser.MEM_A)
# 出力:IntEnumUser.MEM_A
# __format__
print(f'{IntEnumUser.MEM_C}')
# 出力
# [~3.10] 3
# [3.11~] IntEnumUser.MEM_C

# IntEnum 継承
class IntEnumChild(IntEnum):
    MEM_A = 1
    MEM_B = 2
    MEM_C = 3

# __str__
print(IntEnumChild.MEM_A)
# 出力
# [~3.10] IntEnumChild.MEM_A
# [3.11~] 1
# __format__
print(f'{IntEnumChild.MEM_C}')
# 出力:3

# 型チェック
i = 123
# isinstance【インスタンス判定】
print(isinstance(i, int))
# 出力:True
print(isinstance(IntEnumUser.MEM_A, int))
# 出力:True
print(isinstance(IntEnumChild.MEM_A, int))
# 出力:True
# type【型クラス】
print(type(i))
# 出力:<class 'int'>
print(type(IntEnumUser.MEM_B))
# 出力:<enum 'IntEnumUser'>
print(type(int(IntEnumUser.MEM_B)))
# 出力:<class 'int'>
print(type(IntEnumChild.MEM_B))
# 出力:<enum 'IntEnumChild'>
print(type(int(IntEnumChild.MEM_B)))
# 出力:<class 'int'>

IntEnum 例:値の自動定義

from enum import IntEnum, auto

# auto【値自動取得】
class IntEnumAuto(IntEnum):
    MEM_A = auto()
    MEM_B = auto()
    MEM_X = 101
    MEM_Y = auto()

    def print_details(self):
        print(self, self.name, self.value, sep=' / ')


# メンバ参照
for mem in IntEnumAuto:
    mem.print_details()
# 出力
# 1 / MEM_A / 1
# 2 / MEM_B / 2
# 101 / MEM_X / 101
# 102 / MEM_Y / 102

# auto カスタマイズ
class IntEnumAutoUser(IntEnum):
    # Enum._generate_next_value_【auto カスタマイズ】
    @staticmethod
    def _generate_next_value_(name, start, count, last_values):
        print(f'{name=}, {start=}, {count=}, {last_values=}')
        return (count + 1) * 10
    MEM_A = auto()
    MEM_B = auto()
    MEM_C = auto()

    def print_details(self):
        print(self, self.name, self.value, sep=' / ')
# 出力
# name='MEM_A', start=1, count=0, last_values=[]
# name='MEM_B', start=1, count=1, last_values=[10]
# name='MEM_C', start=1, count=2, last_values=[10, 20]

# メンバ参照
for mem in IntEnumAutoUser:
    mem.print_details()
# 出力
# 10 / MEM_A / 10
# 20 / MEM_B / 20
# 30 / MEM_C / 30

IntEnum 例:制約指定

from enum import IntEnum, unique, verify, UNIQUE, CONTINUOUS

# 別名有効 (デフォルト)
class IntEnumDefault(IntEnum):
    MEM_A = 1
    MEM_B = 2
    MEM_C = 3
    MEM_X = MEM_A  # 別名

# @unique【一意値】
@unique
class IntEnumUniqueA(IntEnum):
    MEM_A = 1
    MEM_B = 2
    MEM_C = 3
    # MEM_X = MEM_A  # 別名:例外
    # ValueError: duplicate values found in <enum 'IntEnumUniqueA'>: MEM_X -> MEM_A

# @verify(UNIQUE)【一意値】
@verify(UNIQUE)
class IntEnumUniqueB(IntEnum):
    MEM_A = 1
    MEM_B = 2
    MEM_C = 3
    # MEM_X = MEM_A  # 別名:例外
    # ValueError: aliases found in <enum 'IntEnumUniqueB'>: MEM_X -> MEM_A

# @verify(CONTINUOUS)【連続値】
@verify(CONTINUOUS)
class IntEnumContinuous(IntEnum):
    MEM_A = 1
    MEM_B = 2
    MEM_C = 3
    # MEM_X = 7  # 不連続:例外
    # ValueError: invalid enum 'IntEnumContinuous': missing values 4, 5, 6

# _order_【定義順】
class IntEnumOrder(IntEnum):
    # _order_ = 'MEM_C MEM_B MEM_A'  # 例外
    MEM_A = 1
    MEM_B = 2
    MEM_C = 3
# TypeError: member order does not match _order_:
#   ['MEM_A', 'MEM_B', 'MEM_C']
#   ['MEM_C', 'MEM_B', 'MEM_A']

IntEnum 例:メンバ参照

from enum import IntEnum

class IntEnumBasic(IntEnum):
    MEM_A = 1
    MEM_B = 2
    MEM_C = 3
    MEM_X = MEM_A  # 別名

# EnumType.__len__(cls)【メンバ数】len(列挙型)
print(len(IntEnumBasic))
# 出力:3

# EnumType.__iter__(cls)【イテレータ (列挙型)】
# EnumType.__reversed__(cls)【逆順】
for mem in IntEnumBasic:
    print(mem)
# 出力
# 1
# 2
# 3
for mem in reversed(IntEnumBasic):
    print(mem)
# 出力
# 3
# 2
# 1
print(list(IntEnumBasic))
# 出力:[<IntEnumBasic.MEM_A: 1>, <IntEnumBasic.MEM_B: 2>, <IntEnumBasic.MEM_C: 3>]
print(list(reversed(IntEnumBasic)))
# 出力:[<IntEnumBasic.MEM_C: 3>, <IntEnumBasic.MEM_B: 2>, <IntEnumBasic.MEM_A: 1>]
print([mem for mem in IntEnumBasic])
# 出力:[<IntEnumBasic.MEM_A: 1>, <IntEnumBasic.MEM_B: 2>, <IntEnumBasic.MEM_C: 3>]
print([mem.name for mem in IntEnumBasic])
# 出力:['MEM_A', 'MEM_B', 'MEM_C']
print([mem.value for mem in IntEnumBasic])
# 出力:[1, 2, 3]

# __members__【全メンバ列挙】
for name, mem in IntEnumBasic.__members__.items():
    print(name, mem, sep=' / ')
# 出力
# MEM_A / 1
# MEM_B / 2
# MEM_C / 3
# MEM_X / 1

# 別名
alias = [name for name, mem in IntEnumBasic.__members__.items() if mem.name != name]
print(alias)
# 出力:['MEM_X']

# EnumType.__getitem__(cls)【名前アクセス】enumtype['メンバ名']
lst = ['MEM_A', 'MEM_B', 'MEM_C', 'MEM_X', 'MEM_XYZ']
for name in lst:
    print(name, IntEnumBasic[name], sep=' / ')
# 出力
# MEM_A / 1
# MEM_B / 2
# MEM_C / 3
# MEM_X / 1
# 例外:KeyError: 'MEM_XYZ'

# EnumType.__call__(cls)【値アクセス】enumtype(メンバ値)
lst = [1, 2, 3, 99]
for value in lst:
    print(f'{value} / ', end='')
    print(IntEnumBasic(value))
# 出力
# 1 / 1
# 2 / 2
# 3 / 3
# 99 /
# 例外:ValueError: 99 is not a valid ~

# Enum._missing_(cls)【未検索処理】
class IntEnumMissing(IntEnum):
    MEM_ZERO = 0
    MEM_A = 1

    @classmethod
    def _missing_(cls, value):
        print(f'_missing_({cls}, {value})')
        return cls.MEM_ZERO

print(IntEnumMissing(0))
# 出力:0
print(IntEnumMissing(1))
# 出力:1
print(IntEnumMissing(99))
# 出力
# _missing_(<enum 'IntEnumMissing'>, 99)
# 0

IntEnum 例:所属・演算・比較

from enum import IntEnum

class IntEnumBasic(IntEnum):
    MEM_A = 1
    MEM_B = 2
    MEM_C = 3
    MEM_X = MEM_A  # 別名


# EnumType.__contains__(cls)【所属判定 (列挙型)】(メンバ | メンバ値) in 列挙型
print(IntEnumBasic.MEM_A in IntEnumBasic)
# 出力:True
print(IntEnumBasic.MEM_B in IntEnumBasic)
# 出力:True
print(IntEnumBasic.MEM_C in IntEnumBasic)
# 出力:True
print(IntEnumBasic.MEM_X in IntEnumBasic)
# 出力:True
print(1 in IntEnumBasic)
# 出力:True
print(2 in IntEnumBasic)
# 出力:True
print(3 in IntEnumBasic)
# 出力:True
print(9 in IntEnumBasic)
# 出力:False
print(9 not in IntEnumBasic)
# 出力:True

# 演算
value = IntEnumBasic.MEM_A + IntEnumBasic.MEM_B
print(value, type(value))
# 出力:3 <class 'int'>
value = IntEnumBasic.MEM_C + 10
print(value, type(value))
# 出力:13 <class 'int'>
value = IntEnumBasic.MEM_C + 100.0
print(value, type(value))
# 出力:103.0 <class 'float'>

# is・is not【同一性比較】
class IntEnumCheck(IntEnum):
    MEM_A = 1

print(IntEnumBasic.MEM_A is IntEnumBasic.MEM_A)
# 出力:True
print(IntEnumBasic.MEM_A is IntEnumBasic.MEM_X)
# 出力:True
print(IntEnumBasic.MEM_A is not IntEnumBasic.MEM_B)
# 出力:True
print(IntEnumBasic.MEM_A is not IntEnumCheck.MEM_A)
# 出力:True

# ==・!=【等価比較】
print(IntEnumBasic.MEM_A == IntEnumBasic.MEM_A)
# 出力:True
print(IntEnumBasic.MEM_A == IntEnumBasic.MEM_X)
# 出力:True
print(IntEnumBasic.MEM_A != IntEnumBasic.MEM_B)
# 出力:True
print(IntEnumBasic.MEM_A != IntEnumCheck.MEM_A)
# 出力:False
print(IntEnumBasic.MEM_A == 1)
# 出力:True

# 大小比較
print(IntEnumBasic.MEM_A < IntEnumBasic.MEM_B < IntEnumBasic.MEM_C)
# 出力:True

Flag【列挙型 (ビットフラグ)】3.63.11

メモ

メソッド

メソッド備考
__contains__(
    self (メンバ),
    value)
所属判定 (列挙子:ビットフラグ)〔例:各列挙型参照〕
メンバ in メンバ (列挙子)
メンバ not in メンバ (列挙子)
所属有無 (True:所属あり / False:所属なし)
valueメンバ
関連:EnumType.__contains__(cls)【所属判定 (列挙型)】
__iter__(self (メンバ)) 3.11 イテレータ (列挙子:ビットフラグ)〔例:各列挙型参照〕
関連:EnumType.__iter__(cls)【イテレータ (列挙型)】
__len__(self (メンバ)) 3.11 ビットフラグ数〔例:各列挙型参照〕
len(メンバ (列挙子))
関連:EnumType.__len__(cls)【メンバ数】
__bool__(self (メンバ)) 真偽値判定〔例:各列挙型参照〕
bool(メンバ)
真偽値 (値が0:False / その他:True)
__or__(
    self (メンバ),
    other (他のメンバ))
OR:ビット論理和〔例:各列挙型参照〕
メンバ | 他のメンバ
結果のメンバ
__and__(
    self (メンバ),
    other (他のメンバ))
AND:ビット論理積〔例:各列挙型参照〕
メンバ & 他のメンバ
結果のメンバ
__xor__(
    self (メンバ),
    other (他のメンバ))
XOR:ビット排他的論理和〔例:各列挙型参照〕
メンバ ^ 他のメンバ
結果のメンバ
__invert__(self (メンバ)) 反転:1の補数〔例:各列挙型参照〕
メンバにないビットフラグは無視 (Flagのデフォルト)
メンバにないビットフラグも有効 (IntFlagのデフォルト)
(FlagBoundary【範囲外値の制御】参照)
~メンバ
結果のメンバ
_numeric_repr_() 3.11 メンバ定義がないビットフラグの数値フォーマット関数

概要

  • ビットフラグ値の列挙型
    • 基本は単独ビットフラグ 3.11
    • ビットフラグなし (0)は特殊値
    • 複数ビットフラグ可 (デフォルト)
    • 別名可 (デフォルト)
  • Enum【列挙型 (基本クラス)】のサブクラス
    • ビット関連の演算結果もFlag【列挙型 (ビットフラグ)】

使用方法

値の自動定義

制約指定

メンバ参照

所属・演算・比較

その他

関連


Flag 例:使用方法

from enum import Flag, unique

@unique
class BitFlag(Flag):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100
    FLAG_ABC = FLAG_A | FLAG_B | FLAG_C  # 複数ビットフラグ
    # FLAG_X = FLAG_A  # 別名:ValueError 例外
    # ValueError: duplicate values found in <flag 'BitFlag'>: FLAG_X -> FLAG_A

    # Enum.name【メンバ名】
    # Enum.value【メンバ値】
    def print_details(self):
        print(self, self.name, self.value, sep=' / ')


# メンバ参照
for mem in BitFlag:
    mem.print_details()
# 出力
# [~3.10]:複数ビットフラグ あり
# BitFlag.FLAG_A / FLAG_A / 1
# BitFlag.FLAG_B / FLAG_B / 2
# BitFlag.FLAG_C / FLAG_C / 4
# BitFlag.FLAG_ABC / FLAG_ABC / 7
# [3.11~]:複数ビットフラグ なし
# BitFlag.FLAG_A / FLAG_A / 1
# BitFlag.FLAG_B / FLAG_B / 2
# BitFlag.FLAG_C / FLAG_C / 4

# メンバ参照 (複数ビットフラグ あり)
for name, mem in BitFlag.__members__.items():
        mem.print_details()
# 出力
# BitFlag.FLAG_A / FLAG_A / 1
# BitFlag.FLAG_B / FLAG_B / 2
# BitFlag.FLAG_C / FLAG_C / 4
# BitFlag.FLAG_ABC / FLAG_ABC / 7

Flag 例:値の自動定義

from enum import Flag, auto

# auto【値自動取得】
class BitFlag(Flag):
    FLAG_A = auto()
    FLAG_B = auto()
    FLAG_C = auto()
    FLAG_X = 0b0100_0000
    FLAG_Y = auto()

    def print_details(self):
        print(f'{self} / {self.name} / {self.value:#011_b}')


# メンバ参照
for mem in BitFlag:
    mem.print_details()
# 出力
# BitFlag.FLAG_A / FLAG_A / 0b0000_0001
# BitFlag.FLAG_B / FLAG_B / 0b0000_0010
# BitFlag.FLAG_C / FLAG_C / 0b0000_0100
# BitFlag.FLAG_X / FLAG_X / 0b0100_0000
# BitFlag.FLAG_Y / FLAG_Y / 0b1000_0000

# auto カスタマイズ
class BitFlagUser(Flag):
    # Enum._generate_next_value_【auto カスタマイズ】
    @staticmethod
    def _generate_next_value_(name, start, count, last_values):
        print(f'{name=} {start=} {count=} {last_values=}')
        return 2**(count + 1)
    FLAG_A = auto()
    FLAG_B = auto()
    FLAG_C = auto()

    def print_details(self):
        print(f'{self} / {self.name} / {self.value:#06b}')
# 出力
# name='FLAG_A' start=1 count=0 last_values=[]
# name='FLAG_B' start=1 count=1 last_values=[2]
# name='FLAG_C' start=1 count=2 last_values=[2, 4]


# メンバ参照
for mem in BitFlagUser:
    mem.print_details()
# 出力
# BitFlagUser.FLAG_A / FLAG_A / 0b0010
# BitFlagUser.FLAG_B / FLAG_B / 0b0100
# BitFlagUser.FLAG_C / FLAG_C / 0b1000

Flag 例:制約指定

from enum import Flag, unique, verify, UNIQUE, NAMED_FLAGS
from enum import STRICT, CONFORM, EJECT, KEEP

# 別名有効 (デフォルト)
class BitFlag(Flag):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100
    FLAG_ABC = FLAG_A | FLAG_B | FLAG_C  # 複数ビットフラグ
    FLAG_X = FLAG_A  # 別名

# @unique【一意値】
@unique
class BitFlagA(Flag):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100
    FLAG_ABC = FLAG_A | FLAG_B | FLAG_C  # 複数ビットフラグ
    # FLAG_X = FLAG_A  # 別名:ValueError 例外
    # ValueError: duplicate values found in <flag 'BitFlagA'>: FLAG_X -> FLAG_A

# @verify(UNIQUE)【一意値】
@verify(UNIQUE)
class BitFlagB(Flag):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100
    FLAG_ABC = FLAG_A | FLAG_B | FLAG_C  # 複数ビットフラグ
    # FLAG_X = FLAG_A  # 別名:ValueError 例外
    # ValueError: aliases found in <flag 'BitFlagB'>: FLAG_X -> FLAG_A

# 複数ビットフラグ定義:有効 (デフォルト)
class BitFlagC(Flag):
    FLAG_AB = 0b0011  # 複数ビットフラグ
    FLAG_C = 0b0100

# 複数ビットフラグ定義:正常指定
@verify(NAMED_FLAGS)
class BitFlagD(Flag):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100
    FLAG_AB = 0b0011  # 複数ビットフラグ
    FLAG_BC = FLAG_B | FLAG_C  # 複数ビットフラグ

# 複数ビットフラグ定義:単独ビット定義必要
@verify(NAMED_FLAGS)
class BitFlagE(Flag):
    FLAG_C = 0b0100
    # FLAG_AB = 0b0011  # 複数ビットフラグ:ValueError 例外
    # ValueError: invalid Flag 'BitFlagE': alias FLAG_AB is ~

# 範囲外の値:boundary 省略 (boundary=STRICT:ValueError 例外)
class BitFlagDefault(Flag):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100

print(BitFlagDefault(0b0111))  # 範囲内
# 出力:BitFlagDefault.FLAG_A|FLAG_B|FLAG_C
# print(BitFlagDefault(0b1001))  # 範囲外:ValueError 例外
# ValueError: <flag 'BitFlagDefault'> invalid value 9
#     given 0b0 1001
#   allowed 0b0 0111

# 範囲外の値:ValueError 例外 (boundary=STRICT)
class BitFlagStrict(Flag, boundary=STRICT):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100

print(BitFlagStrict(0b0111))  # 範囲内
# 出力:BitFlagStrict.FLAG_A|FLAG_B|FLAG_C
# print(BitFlagStrict(0b1001))  # 範囲外:ValueError 例外
# ValueError: <flag 'BitFlagStrict'> invalid value 9
#     given 0b0 1001
#   allowed 0b0 0111

# 範囲外の値:無効ビットフラグ値削除 (boundary=CONFORM)
class BitFlagConform(Flag, boundary=CONFORM):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100

print(BitFlagConform(0b0111))  # 範囲内
# 出力:BitFlagConform.FLAG_A|FLAG_B|FLAG_C
print(BitFlagConform(0b1001))  # 範囲外
# 出力:BitFlagConform.FLAG_A

# 範囲外の値:int とみなす (boundary=EJECT)
class BitFlagEject(Flag, boundary=EJECT):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100

print(BitFlagEject(0b0111))  # 範囲内
# 出力:BitFlagEject.FLAG_A|FLAG_B|FLAG_C
print(BitFlagEject(0b1001))  # 範囲外
# 出力:9

# 範囲外の値:保持し列挙型のまま (boundary=KEEP)
class BitFlagKeep(Flag, boundary=KEEP):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100

print(BitFlagKeep(0b0111))  # 範囲内
# 出力:BitFlagKeep.FLAG_A|FLAG_B|FLAG_C
print(BitFlagKeep(0b1001))  # 範囲外
# 出力:BitFlagKeep.FLAG_A|8

# _order_【定義順】
class BitFlagOrder(Flag):
    # _order_ = 'FLAG_C FLAG_B FLAG_A'  # 例外
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100
# TypeError: member order does not match _order_:
#   ['FLAG_A', 'FLAG_B', 'FLAG_C']
#   ['FLAG_C', 'FLAG_B', 'FLAG_A']

Flag 例:メンバ参照

from enum import Flag, show_flag_values

class BitFlag(Flag):
    FLAG_ZERO = 0  # ビットなし
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100
    FLAG_ABC = FLAG_A | FLAG_B | FLAG_C  # 複数ビットフラグ
    FLAG_X = FLAG_A  # 別名

# EnumType.__len__(cls)【メンバ数】len(列挙型)
print(len(BitFlag))
# 出力:3

# EnumType.__iter__(cls)【イテレータ (列挙型)】
# EnumType.__reversed__(cls)【逆順】
for mem in BitFlag:
    print(mem)
# 出力
# BitFlag.FLAG_A
# BitFlag.FLAG_B
# BitFlag.FLAG_C
for mem in reversed(BitFlag):
    print(mem)
# 出力
# BitFlag.FLAG_C
# BitFlag.FLAG_B
# BitFlag.FLAG_A
print(list(BitFlag))
# 出力:[<BitFlag.FLAG_A: 1>, <BitFlag.FLAG_B: 2>, <BitFlag.FLAG_C: 4>]
print(list(reversed(BitFlag)))
# 出力:[<BitFlag.FLAG_C: 4>, <BitFlag.FLAG_B: 2>, <BitFlag.FLAG_A: 1>]
print([mem for mem in BitFlag])
# 出力:[<BitFlag.FLAG_A: 1>, <BitFlag.FLAG_B: 2>, <BitFlag.FLAG_C: 4>]
print([mem.name for mem in BitFlag])
# 出力:['FLAG_A', 'FLAG_B', 'FLAG_C']
print([mem.value for mem in BitFlag])
# 出力:[1, 2, 4]

# __members__【全メンバ列挙】
# Flag.__len__(self)【フラグ数】len(メンバ)
# Flag.__iter__(self)【イテレータ (列挙子:ビットフラグ)】
# show_flag_values【ユーティリティ関数:ビットフラグリスト】
for name, mem in BitFlag.__members__.items():
    print(name, mem, mem.value, len(mem), sep=' / ')
    print([flag for flag in mem], show_flag_values(mem.value))
# 出力
# FLAG_ZERO / BitFlag.FLAG_ZERO / 0 / 0
# [] []
# FLAG_A / BitFlag.FLAG_A / 1 / 1
# [<BitFlag.FLAG_A: 1>] [1]
# FLAG_B / BitFlag.FLAG_B / 2 / 1
# [<BitFlag.FLAG_B: 2>] [2]
# FLAG_C / BitFlag.FLAG_C / 4 / 1
# [<BitFlag.FLAG_C: 4>] [4]
# FLAG_ABC / BitFlag.FLAG_ABC / 7 / 3
# [<BitFlag.FLAG_A: 1>, <BitFlag.FLAG_B: 2>, <BitFlag.FLAG_C: 4>] [1, 2, 4]
# FLAG_X / BitFlag.FLAG_A / 1 / 1
# [<BitFlag.FLAG_A: 1>] [1]
# 別名
alias = [name for name, mem in BitFlag.__members__.items() if mem.name != name]
print(alias)
# 出力:['FLAG_X']

# EnumType.__getitem__(cls)【名前アクセス】enumtype['メンバ名']
lst = ['FLAG_ZERO', 'FLAG_A', 'FLAG_B', 'FLAG_C', 'FLAG_ABC', 'FLAG_X', 'FLAG_XYZ']
for name in lst:
    print(name, BitFlag[name], sep=' / ')
# 出力
# FLAG_ZERO / BitFlag.FLAG_ZERO
# FLAG_A / BitFlag.FLAG_A
# FLAG_B / BitFlag.FLAG_B
# FLAG_C / BitFlag.FLAG_C
# FLAG_ABC / BitFlag.FLAG_ABC
# FLAG_X / BitFlag.FLAG_A
# 例外:KeyError: 'FLAG_XYZ'

# EnumType.__call__(cls)【値アクセス】enumtype(メンバ値)
class BitFlag2(Flag):
    # ビットなし未定義
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100
    FLAG_ABC = FLAG_A | FLAG_B | FLAG_C  # 複数ビットフラグ
    FLAG_X = FLAG_A  # 別名

lst = [0, 0b0001, 0b0010, 0b0100, 0b0011, 0b0101, 0b0110, 0b0111, 0b1111]
for value in lst:
    print(f'{value:#06b} / ', end='')
    print(BitFlag2(value))
# 出力
# 0b0000 / BitFlag2(0)
# 0b0001 / BitFlag2.FLAG_A
# 0b0010 / BitFlag2.FLAG_B
# 0b0100 / BitFlag2.FLAG_C
# 0b0011 / BitFlag2.FLAG_A|FLAG_B
# 0b0101 / BitFlag2.FLAG_A|FLAG_C
# 0b0110 / BitFlag2.FLAG_B|FLAG_C
# 0b0111 / BitFlag2.FLAG_ABC
# 0b1111 /
# 例外:ValueError: <flag 'BitFlag2'> invalid value 15
#     given 0b0 1111
#   allowed 0b0 0111

# Enum._missing_(cls)【未検索処理】
class BitFlagMissing(Flag):
    FLAG_ZERO = 0
    FLAG_A = 0b0001
    @classmethod
    def _missing_(cls, value):
        print(f'_missing_({cls}, {value})')
        return cls.FLAG_ZERO

print(BitFlagMissing(0))
# 出力:BitFlagMissing.FLAG_ZERO
print(BitFlagMissing(0b0001))
# 出力:BitFlagMissing.FLAG_A
print(BitFlagMissing(0b1111))
# 出力
# _missing_(<flag 'BitFlagMissing'>, 15)
# BitFlagMissing.FLAG_ZERO

Flag 例:所属・演算・比較

from enum import Flag

class BitFlag(Flag):
    FLAG_ZERO = 0
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100
    FLAG_D = 0b1000
    FLAG_H = 0b1000_0000
    FLAG_AB = FLAG_A | FLAG_B  # 複数ビットフラグ
    FLAG_AC = FLAG_A | FLAG_C  # 複数ビットフラグ
    FLAG_ABC = FLAG_A | FLAG_B | FLAG_C  # 複数ビットフラグ
    FLAG_X = FLAG_A  # 別名

    def print_details(self):
        print(f'{self} / {self.name} / {self.value:#011_b}')


# EnumType.__contains__(cls)【所属判定 (列挙型)】(メンバ | メンバ値) in 列挙型
print(BitFlag.FLAG_A in BitFlag)
# 出力:True
print(BitFlag.FLAG_ABC in BitFlag)
# 出力:True
print(BitFlag.FLAG_X in BitFlag)
# 出力:True
print(0b0001 in BitFlag)
# 出力:True
print(0b0111 in BitFlag)
# 出力:True
print(0b0101 in BitFlag)
# 出力:True
print(0b1_0000 in BitFlag)
# 出力:False
print(0b1_0000 not in BitFlag)
# 出力:True
print(BitFlag.FLAG_ZERO in BitFlag)
# 出力:True
print(0 in BitFlag)
# 出力:True

# Flag.__contains__(self)【所属判定 (列挙子:ビットフラグ)】列挙子 in 列挙子
print(BitFlag.FLAG_A in BitFlag.FLAG_ABC)
# 出力:True
print(BitFlag.FLAG_B in BitFlag.FLAG_ABC)
# 出力:True
print(BitFlag.FLAG_C in BitFlag.FLAG_ABC)
# 出力:True
print(BitFlag.FLAG_D in BitFlag.FLAG_ABC)
# 出力:False
flag_ac = BitFlag.FLAG_A | BitFlag.FLAG_C
print(flag_ac in BitFlag.FLAG_ABC)
# 出力:True
flag_ad = BitFlag.FLAG_A | BitFlag.FLAG_D
print(flag_ad in BitFlag.FLAG_ABC)
# 出力:False
print(flag_ad not in BitFlag.FLAG_ABC)
# 出力:True
print(BitFlag.FLAG_ZERO in BitFlag.FLAG_ABC)
# 出力:True
flag_0 = BitFlag(0)
print(flag_0 in BitFlag.FLAG_ABC)
# 出力:True

# Flag.__bool__(self)【真偽値判定】BOOL
print(bool(BitFlag.FLAG_A))
# 出力:True
print(bool(BitFlag.FLAG_ABC))
# 出力:True
flag_bc = BitFlag.FLAG_B | BitFlag.FLAG_C
print(bool(flag_bc))
# 出力:True
print(bool(BitFlag.FLAG_ZERO))
# 出力:False
flag_0 = BitFlag(0)
print(bool(flag_0))
# 出力:False

# Flag.__or__(self)【OR:ビット論理和】|
#                    0011 | 0101
flag_or = BitFlag.FLAG_AB | BitFlag.FLAG_AC
flag_or.print_details()
# 出力:BitFlag.FLAG_ABC / FLAG_ABC / 0b0000_0111

# Flag.__and__(self)【AND:ビット論理積】&
#                     0011 & 0101
flag_and = BitFlag.FLAG_AB & BitFlag.FLAG_AC
flag_and.print_details()
# 出力:BitFlag.FLAG_A / FLAG_A / 0b0000_0001
#                     0001 & 0010
flag_and = BitFlag.FLAG_A & BitFlag.FLAG_B
flag_and.print_details()
# 出力:BitFlag.FLAG_ZERO / FLAG_ZERO / 0b0000_0000

# Flag.__xor__(self)【XOR:ビット排他的論理和】^
#                     0011 ^ 0101
flag_xor = BitFlag.FLAG_AB ^ BitFlag.FLAG_AC
flag_xor.print_details()
# 出力:BitFlag.FLAG_B|FLAG_C / FLAG_B|FLAG_C / 0b0000_0110
#                     0001 ^ 0001
flag_xor = BitFlag.FLAG_A ^ BitFlag.FLAG_A
flag_xor.print_details()
# 出力:BitFlag.FLAG_ZERO / FLAG_ZERO / 0b0000_0000

# Flag.__invert__(self)【反転:1の補数】~
#             ~0011
flag_invert = ~BitFlag.FLAG_AB
flag_invert.print_details()
# 出力:BitFlag.FLAG_C|FLAG_D|FLAG_H / FLAG_C|FLAG_D|FLAG_H / 0b1000_1100
#             ~1000_0000
flag_invert = ~BitFlag.FLAG_H
flag_invert.print_details()
# 出力:BitFlag.FLAG_A|FLAG_B|FLAG_C|FLAG_D / FLAG_A|FLAG_B|FLAG_C|FLAG_D / 0b0000_1111

# is・is not【同一性比較】
class BitFlagCheck(Flag):
    FLAG_ZERO = 0
    FLAG_A = 0b0001

print(BitFlag.FLAG_A is BitFlag.FLAG_A)
# 出力:True
print(BitFlag.FLAG_A is BitFlag.FLAG_X)
# 出力:True
print(BitFlag.FLAG_A is not BitFlag.FLAG_B)
# 出力:True
print(BitFlag.FLAG_A is not BitFlagCheck.FLAG_A)
# 出力:True

# ==・!=【等価比較】
print(BitFlag.FLAG_A == BitFlag.FLAG_A)
# 出力:True
print(BitFlag.FLAG_A == BitFlag.FLAG_X)
# 出力:True
print(BitFlag.FLAG_A != BitFlag.FLAG_B)
# 出力:True
print(BitFlag.FLAG_A != BitFlagCheck.FLAG_A)
# 出力:True
print(BitFlag.FLAG_A == 1)
# 出力:False

# 大小比較
# print(BitFlag.FLAG_A < BitFlag.FLAG_B < BitFlag.FLAG_C)  # 例外
# TypeError: '<' not supported between instances of 'BitFlag' and 'BitFlag'
print(BitFlag.FLAG_A.value < BitFlag.FLAG_B.value < BitFlag.FLAG_C.value)
# 出力:True

IntFlag【列挙型 (整数ビットフラグ)】3.63.11

メモ

概要

使用方法

互換性

  • 整数値からの置換が容易になるように、以下の仕様
    • __str__:メンバ メンバ値 (整数値) 3.11
    • __format__:メンバ値 (整数値)
  • 型判定
    • isinstance【インスタンス判定】:int【整数型】と判定されるので問題なし
    • type【型クラス】:enum【列挙型】と判定されるので、int【整数型】に変換が必要

値の自動定義

制約指定

メンバ参照

所属・演算・比較

その他

関連


IntFlag 例:使用方法

from enum import IntFlag, unique

@unique
class IntBitFlag(IntFlag):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100
    FLAG_D = '1000', 2  # 2進数
    FLAG_E = '20', 8   # 8進数
    FLAG_F = '20', 16  # 16進数
    FLAG_ABC = FLAG_A | FLAG_B | FLAG_C  # 複数ビットフラグ
    # FLAG_X = FLAG_A  # 別名:ValueError 例外
    # ValueError: duplicate values found in <flag 'IntBitFlag'>: FLAG_X -> FLAG_A

    # Enum.name【メンバ名】
    # Enum.value【メンバ値】
    def print_details(self):
        print(self, self.name, self.value, sep=' / ')

# メンバ参照
for mem in IntBitFlag:
    mem.print_details()
# 出力
# [~3.10]:複数ビットフラグ あり
# IntBitFlag.FLAG_A / FLAG_A / 1
# IntBitFlag.FLAG_B / FLAG_B / 2
# IntBitFlag.FLAG_C / FLAG_C / 4
# IntBitFlag.FLAG_D / FLAG_D / 8
# IntBitFlag.FLAG_E / FLAG_E / 16
# IntBitFlag.FLAG_F / FLAG_F / 32
# IntBitFlag.FLAG_ABC / FLAG_ABC / 7
# [3.11~]:複数ビットフラグ なし
# 1 / FLAG_A / 1
# 2 / FLAG_B / 2
# 4 / FLAG_C / 4
# 8 / FLAG_D / 8
# 16 / FLAG_E / 16
# 32 / FLAG_F / 32

# メンバ参照 (複数ビットフラグ あり)
for name, mem in IntBitFlag.__members__.items():
        mem.print_details()
# 出力
# [~3.10]
# IntBitFlag.FLAG_A / FLAG_A / 1
# IntBitFlag.FLAG_B / FLAG_B / 2
# IntBitFlag.FLAG_C / FLAG_C / 4
# IntBitFlag.FLAG_D / FLAG_D / 8
# IntBitFlag.FLAG_E / FLAG_E / 16
# IntBitFlag.FLAG_F / FLAG_F / 32
# IntBitFlag.FLAG_ABC / FLAG_ABC / 7
# [3.11~]
# 1 / FLAG_A / 1
# 2 / FLAG_B / 2
# 4 / FLAG_C / 4
# 8 / FLAG_D / 8
# 16 / FLAG_E / 16
# 32 / FLAG_F / 32
# 7 / FLAG_ABC / 7

IntFlag 例:互換性

from enum import Flag, IntFlag

# intとFlag 継承
class IntBitFlagA(int, Flag):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100

# __str__
print(IntBitFlagA.FLAG_A)
# 出力:IntBitFlagA.FLAG_A
# __format__
print(f'{IntBitFlagA.FLAG_C}')
# 出力
# [~3.10] 4
# [3.11~] IntBitFlagA.FLAG_C

# IntFlag 継承
class IntBitFlagB(IntFlag):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100

# __str__
print(IntBitFlagB.FLAG_A)
# 出力
# [~3.10] IntBitFlagB.FLAG_A
# [3.11~] 1
# __format__
print(f'{IntBitFlagB.FLAG_C}')
# 出力:4

# 型チェック
i = 123
# isinstance【インスタンス判定】
print(isinstance(i, int))
# 出力:True
print(isinstance(IntBitFlagA.FLAG_A, int))
# 出力:True
print(isinstance(IntBitFlagB.FLAG_A, int))
# 出力:True

# type【型クラス】
print(type(i))
# 出力:<class 'int'>
print(type(IntBitFlagA.FLAG_A))
# 出力:<flag 'IntBitFlagA'>
print(type(int(IntBitFlagA.FLAG_A)))
# 出力:<class 'int'>
print(type(IntBitFlagB.FLAG_A))
# 出力:<flag 'IntBitFlagB'>
print(type(int(IntBitFlagB.FLAG_A)))
# 出力:<class 'int'>

IntFlag 例:値の自動定義

from enum import IntFlag, auto

# auto【値自動取得】
class IntBitFlag(IntFlag):
    FLAG_A = auto()
    FLAG_B = auto()
    FLAG_C = auto()
    FLAG_X = 0b0100_0000
    FLAG_Y = auto()

    def print_details(self):
        print(f'{self:#011_b} / {self.name} / {self.value:#011_b}')

# メンバ参照
for mem in IntBitFlag:
    mem.print_details()
# 出力
# 0b0000_0001 / FLAG_A / 0b0000_0001
# 0b0000_0010 / FLAG_B / 0b0000_0010
# 0b0000_0100 / FLAG_C / 0b0000_0100
# 0b0100_0000 / FLAG_X / 0b0100_0000
# 0b1000_0000 / FLAG_Y / 0b1000_0000

# auto カスタマイズ
class IntBitFlagUser(IntFlag):
    @staticmethod
    def _generate_next_value_(name, start, count, last_values):
        print(f'{name=} {start=} {count=} {last_values=}')
        return 2**(count + 1)
    FLAG_A = auto()
    FLAG_B = auto()
    FLAG_C = auto()

    def print_details(self):
        print(f'{self:#06b} / {self.name} / {self.value:#06b}')

# 出力
# name='FLAG_A' start=1 count=0 last_values=[]
# name='FLAG_B' start=1 count=1 last_values=[2]
# name='FLAG_C' start=1 count=2 last_values=[2, 4]

# メンバ参照
for mem in IntBitFlagUser:
    mem.print_details()
# 出力
# 0b0010 / FLAG_A / 0b0010
# 0b0100 / FLAG_B / 0b0100
# 0b1000 / FLAG_C / 0b1000

IntFlag 例:制約指定

from enum import IntFlag, unique, verify, UNIQUE, NAMED_FLAGS
from enum import STRICT, CONFORM, EJECT, KEEP

# 別名有効 (デフォルト)
class IntBitFlag(IntFlag):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100
    FLAG_ABC = FLAG_A | FLAG_B | FLAG_C  # 複数ビットフラグ
    FLAG_X = FLAG_A  # 別名

# @unique【一意値】
@unique
class IntBitFlagA(IntFlag):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100
    FLAG_ABC = FLAG_A | FLAG_B | FLAG_C  # 複数ビットフラグ
    # FLAG_X = FLAG_A  # 別名:ValueError 例外
    # ValueError: duplicate values found in <flag 'IntBitFlagA'>: FLAG_X -> FLAG_A

# @verify(UNIQUE)【一意値】
@verify(UNIQUE)
class IntBitFlagB(IntFlag):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100
    FLAG_ABC = FLAG_A | FLAG_B | FLAG_C  # 複数ビットフラグ
    # FLAG_X = FLAG_A  # 別名:ValueError 例外
    # ValueError: aliases found in <flag 'IntBitFlagB'>: FLAG_X -> FLAG_A

# 複数ビットフラグ定義:有効 (デフォルト)
class IntBitFlagC(IntFlag):
    FLAG_AB = 0b0011  # 複数ビットフラグ
    FLAG_C = 0b0100

# 複数ビットフラグ定義:正常指定
@verify(NAMED_FLAGS)
class IntBitFlagD(IntFlag):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100
    FLAG_AB = 0b0011  # 複数ビットフラグ
    FLAG_BC = FLAG_B | FLAG_C  # 複数ビットフラグ

# 複数ビットフラグ定義:単独ビット定義必要
@verify(NAMED_FLAGS)
class IntBitFlagE(IntFlag):
    FLAG_C = 0b0100
    # FLAG_AB = 0b0011  # 複数ビットフラグ:ValueError 例外
    # ValueError: invalid Flag 'IntBitFlagE': alias FLAG_AB is ~

# 範囲外の値:boundary 省略 (boundary=KEEP:保持し列挙型のまま)
class IntBitFlagDefault(IntFlag):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100

flag = IntBitFlagDefault(0b0111)  # 範囲内
print(type(flag), flag)
# 出力:<flag 'IntBitFlagDefault'> 7
flag = IntBitFlagDefault(0b1001)  # 範囲外
print(type(flag), flag)
# 出力:<flag 'IntBitFlagDefault'> 9

# 範囲外の値:ValueError 例外 (boundary=STRICT)
class IntBitFlagStrict(IntFlag, boundary=STRICT):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100

flag = IntBitFlagStrict(0b0111)  # 範囲内
print(type(flag), flag)
# 出力:<flag 'IntBitFlagStrict'> 7
# flag = IntBitFlagStrict(0b1001)  # 範囲外:ValueError 例外
# ValueError: <flag 'IntBitFlagStrict'> invalid value 9
#     given 0b0 1001
#   allowed 0b0 0111

# 範囲外の値:無効ビットフラグ値削除 (boundary=CONFORM)
class IntBitFlagConform(IntFlag, boundary=CONFORM):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100

flag = IntBitFlagConform(0b0111)  # 範囲内
print(type(flag), flag)
# 出力:<flag 'IntBitFlagConform'> 7
flag = IntBitFlagConform(0b1001)  # 範囲外
print(type(flag), flag)
# 出力:<flag 'IntBitFlagConform'> 1

# 範囲外の値:int とみなす (boundary=EJECT)
class IntBitFlagEject(IntFlag, boundary=EJECT):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100

flag = IntBitFlagEject(0b0111)  # 範囲内
print(type(flag), flag)
# 出力:<flag 'IntBitFlagEject'> 7
flag = IntBitFlagEject(0b1001)  # 範囲外
print(type(flag), flag)
# 出力:<class 'int'> 9

# 範囲外の値:保持し列挙型のまま (boundary=KEEP)
class IntBitFlagKeep(IntFlag, boundary=KEEP):
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100

flag = IntBitFlagKeep(0b0111)  # 範囲内
print(type(flag), flag)
# 出力:<flag 'IntBitFlagKeep'> 7
flag = IntBitFlagKeep(0b1001)  # 範囲外
print(type(flag), flag)
# 出力:<flag 'IntBitFlagKeep'> 9

# _order_【定義順】
class IntBitFlagOrder(IntFlag):
    # _order_ = 'FLAG_C FLAG_B FLAG_A'  # 例外
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100
# TypeError: member order does not match _order_:
#   ['FLAG_A', 'FLAG_B', 'FLAG_C']
#   ['FLAG_C', 'FLAG_B', 'FLAG_A']

IntFlag 例:メンバ参照

from enum import IntFlag, show_flag_values

class IntBitFlag(IntFlag):
    FLAG_ZERO = 0  # ビットなし
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100
    FLAG_ABC = FLAG_A | FLAG_B | FLAG_C  # 複数ビットフラグ
    FLAG_X = FLAG_A  # 別名

# EnumType.__len__(cls)【メンバ数】len(列挙型)
print(len(IntBitFlag))
# 出力:3

# EnumType.__iter__(cls)【イテレータ (列挙型)】
# EnumType.__reversed__(cls)【逆順】
for mem in IntBitFlag:
    print(mem)
# 出力
# 1
# 2
# 4
for mem in reversed(IntBitFlag):
    print(mem)
# 出力
# 4
# 2
# 1
print(list(IntBitFlag))
# 出力:[<IntBitFlag.FLAG_A: 1>, <IntBitFlag.FLAG_B: 2>, <IntBitFlag.FLAG_C: 4>]
print(list(reversed(IntBitFlag)))
# 出力:[<IntBitFlag.FLAG_C: 4>, <IntBitFlag.FLAG_B: 2>, <IntBitFlag.FLAG_A: 1>]
print([mem for mem in IntBitFlag])
# 出力:[<IntBitFlag.FLAG_A: 1>, <IntBitFlag.FLAG_B: 2>, <IntBitFlag.FLAG_C: 4>]
print([mem.name for mem in IntBitFlag])
# 出力:['FLAG_A', 'FLAG_B', 'FLAG_C']
print([mem.value for mem in IntBitFlag])
# 出力:[1, 2, 4]
print([(mem.name, mem.value) for mem in IntBitFlag])
# 出力:[('FLAG_A', 1), ('FLAG_B', 2), ('FLAG_C', 4)]

# __members__【全メンバ列挙】
# Flag.__len__(self)【フラグ数】len(メンバ)
# Flag.__iter__(self)【イテレータ (列挙子:ビットフラグ)】
# show_flag_values【ユーティリティ関数:ビットフラグリスト】
for name, mem in IntBitFlag.__members__.items():
    print(name, mem, mem.value, len(mem), sep=' / ')
    print([flag for flag in mem], show_flag_values(mem.value))
# 出力
# FLAG_ZERO / 0 / 0 / 0
# [] []
# FLAG_A / 1 / 1 / 1
# [<IntBitFlag.FLAG_A: 1>] [1]
# FLAG_B / 2 / 2 / 1
# [<IntBitFlag.FLAG_B: 2>] [2]
# FLAG_C / 4 / 4 / 1
# [<IntBitFlag.FLAG_C: 4>] [4]
# FLAG_ABC / 7 / 7 / 3
# [<IntBitFlag.FLAG_A: 1>, <IntBitFlag.FLAG_B: 2>, <IntBitFlag.FLAG_C: 4>] [1, 2, 4]
# FLAG_X / 1 / 1 / 1
# [<IntBitFlag.FLAG_A: 1>] [1]
# 別名
print([name for name, mem in IntBitFlag.__members__.items() if mem.name != name])
# 出力:['FLAG_X']

# EnumType.__getitem__(cls)【名前アクセス】enumtype['メンバ名']
lst = ['FLAG_ZERO', 'FLAG_A', 'FLAG_B', 'FLAG_C', 'FLAG_ABC', 'FLAG_X', 'FLAG_XYZ']
for name in lst:
    print(name, IntBitFlag[name], sep=' / ')
# 出力
# FLAG_ZERO / 0
# FLAG_A / 1
# FLAG_B / 2
# FLAG_C / 4
# FLAG_ABC / 7
# FLAG_X / 1
# 例外:KeyError: 'FLAG_XYZ'

# EnumType.__call__(cls)【値アクセス】enumtype(メンバ値)
class IntBitFlag2(IntFlag):
    # ビットなし未定義
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100
    FLAG_ABC = FLAG_A | FLAG_B | FLAG_C  # 複数ビットフラグ
    FLAG_X = FLAG_A  # 別名

lst = [0, 0b0001, 0b0010, 0b0100, 0b0011, 0b0101, 0b0110, 0b0111, 0b1111]
for value in lst:
    print(f'{value:#06b} / {IntBitFlag2(value)} / {[IntBitFlag2(value)]}')
# 出力
# 0b0000 / 0 / [<IntBitFlag2: 0>]
# 0b0001 / 1 / [<IntBitFlag2.FLAG_A: 1>]
# 0b0010 / 2 / [<IntBitFlag2.FLAG_B: 2>]
# 0b0100 / 4 / [<IntBitFlag2.FLAG_C: 4>]
# 0b0011 / 3 / [<IntBitFlag2.FLAG_A|FLAG_B: 3>]
# 0b0101 / 5 / [<IntBitFlag2.FLAG_A|FLAG_C: 5>]
# 0b0110 / 6 / [<IntBitFlag2.FLAG_B|FLAG_C: 6>]
# 0b0111 / 7 / [<IntBitFlag2.FLAG_ABC: 7>]
# 0b1111 / 15 / [<IntBitFlag2.FLAG_A|FLAG_B|FLAG_C|FLAG_ABC|8: 15>]

# Enum._missing_(cls)【未検索処理】
class IntBitFlagMissing(IntFlag):
    FLAG_ZERO = 0
    FLAG_A = 0b0001
    @classmethod
    def _missing_(cls, value):
        print(f'_missing_({cls}, {value})')
        return cls.FLAG_ZERO

print(IntBitFlagMissing(0))
# 出力:0
print(IntBitFlagMissing(0b0001))
# 出力:1
print(IntBitFlagMissing(0b1111))
# 出力
# _missing_(<flag 'IntBitFlagMissing'>, 15)
# 0

IntFlag 例:所属・演算・比較

from enum import IntFlag

class IntBitFlag(IntFlag):
    FLAG_ZERO = 0
    FLAG_A = 0b0001
    FLAG_B = 0b0010
    FLAG_C = 0b0100
    FLAG_D = 0b1000
    FLAG_H = 0b1000_0000
    FLAG_AB = FLAG_A | FLAG_B  # 複数ビットフラグ
    FLAG_AC = FLAG_A | FLAG_C  # 複数ビットフラグ
    FLAG_ABC = FLAG_A | FLAG_B | FLAG_C  # 複数ビットフラグ
    FLAG_X = FLAG_A  # 別名

    def print_details(self):
        print(f'{self} / {self.name} / {self.value:#011_b}')


# EnumType.__contains__(cls)【所属判定 (列挙型)】メンバ | メンバ値 in 列挙型
print(IntBitFlag.FLAG_A in IntBitFlag)
# 出力:True
print(IntBitFlag.FLAG_ABC in IntBitFlag)
# 出力:True
print(IntBitFlag.FLAG_X in IntBitFlag)
# 出力:True
print(0b0001 in IntBitFlag)
# 出力:True
print(0b0111 in IntBitFlag)
# 出力:True
print(0b0101 in IntBitFlag)
# 出力:True
print(0b1_0000 in IntBitFlag)
# 出力:False
print(0b1_0000 not in IntBitFlag)
# 出力:True
print(IntBitFlag.FLAG_ZERO in IntBitFlag)
# 出力:True
print(0 in IntBitFlag)
# 出力:True

# Flag.__contains__(self)【所属判定 (列挙子:ビットフラグ)】列挙子 in 列挙子
print(IntBitFlag.FLAG_A in IntBitFlag.FLAG_ABC)
# 出力:True
print(IntBitFlag.FLAG_B in IntBitFlag.FLAG_ABC)
# 出力:True
print(IntBitFlag.FLAG_C in IntBitFlag.FLAG_ABC)
# 出力:True
print(IntBitFlag.FLAG_D in IntBitFlag.FLAG_ABC)
# 出力:False
flag_ac = IntBitFlag.FLAG_A | IntBitFlag.FLAG_C
print(flag_ac in IntBitFlag.FLAG_ABC)
# 出力:True
flag_ad = IntBitFlag.FLAG_A | IntBitFlag.FLAG_D
print(flag_ad in IntBitFlag.FLAG_ABC)
# 出力:False
print(flag_ad not in IntBitFlag.FLAG_ABC)
# 出力:True
print(IntBitFlag.FLAG_ZERO in IntBitFlag.FLAG_ABC)
# 出力:True
flag_0 = IntBitFlag(0)
print(flag_0 in IntBitFlag.FLAG_ABC)
# 出力:True

# Flag.__bool__(self)【真偽値判定】BOOL
print(bool(IntBitFlag.FLAG_A))
# 出力:True
print(bool(IntBitFlag.FLAG_ABC))
# 出力:True
flag_bc = IntBitFlag.FLAG_B | IntBitFlag.FLAG_C
print(bool(flag_bc))
# 出力:True
print(bool(IntBitFlag.FLAG_ZERO))
# 出力:False
flag_0 = IntBitFlag(0)
print(bool(flag_0))
# 出力:False

# Flag.__or__(self)【OR:ビット論理和】|
#                       0011 | 0101
flag_or = IntBitFlag.FLAG_AB | IntBitFlag.FLAG_AC
flag_or.print_details()
# 出力:7 / FLAG_ABC / 0b0000_0111

# Flag.__and__(self)【AND:ビット論理積】&
#                        0011 & 0101
flag_and = IntBitFlag.FLAG_AB & IntBitFlag.FLAG_AC
flag_and.print_details()
# 出力:1 / FLAG_A / 0b0000_0001
#                       0001 & 0010
flag_and = IntBitFlag.FLAG_A & IntBitFlag.FLAG_B
flag_and.print_details()
# 出力:0 / FLAG_ZERO / 0b0000_0000

# Flag.__xor__(self)【XOR:ビット排他的論理和】^
#                        0011 ^ 0101
flag_xor = IntBitFlag.FLAG_AB ^ IntBitFlag.FLAG_AC
flag_xor.print_details()
# 出力:6 / FLAG_B|FLAG_C / 0b0000_0110
#                       0001 ^ 0001
flag_xor = IntBitFlag.FLAG_A ^ IntBitFlag.FLAG_A
flag_xor.print_details()
# 出力:0 / FLAG_ZERO / 0b0000_0000

# Flag.__invert__(self)【反転:1の補数】~
#             ~0011
flag_invert = ~IntBitFlag.FLAG_AB
flag_invert.print_details()
# 出力:252 / FLAG_C|FLAG_D|FLAG_H|112 / 0b1111_1100
#             ~1000_0000
flag_invert = ~IntBitFlag.FLAG_H
flag_invert.print_details()
# 出力:127 / FLAG_A|FLAG_B|FLAG_C|FLAG_D|FLAG_AB|FLAG_AC|FLAG_ABC|112 / 0b0111_1111

# is・is not【同一性比較】
class IntBitFlagCheck(IntFlag):
    FLAG_ZERO = 0
    FLAG_A = 0b0001

print(IntBitFlag.FLAG_A is IntBitFlag.FLAG_A)
# 出力:True
print(IntBitFlag.FLAG_A is IntBitFlag.FLAG_X)
# 出力:True
print(IntBitFlag.FLAG_A is not IntBitFlag.FLAG_B)
# 出力:True
print(IntBitFlag.FLAG_A is not IntBitFlagCheck.FLAG_A)
# 出力:True

# ==・!=【等価比較】
print(IntBitFlag.FLAG_A == IntBitFlag.FLAG_A)
# 出力:True
print(IntBitFlag.FLAG_A == IntBitFlag.FLAG_X)
# 出力:True
print(IntBitFlag.FLAG_A != IntBitFlag.FLAG_B)
# 出力:True
print(IntBitFlag.FLAG_A != IntBitFlagCheck.FLAG_A)
# 出力:False
print(IntBitFlag.FLAG_A == 1)
# 出力:True

# 大小比較
print(IntBitFlag.FLAG_A < IntBitFlag.FLAG_B < IntBitFlag.FLAG_C)
# 出力:True

StrEnum【列挙型 (文字列)】3.11

メモ

概要

使用方法

値の自動定義

制約指定

互換性

  • 既存文字列の置換を考慮し、以下の仕様
    (str【文字列型】Enum【列挙型 (基本クラス)】の継承とは相違)
    • __str__:メンバ値 (文字列)
    • __format__:メンバ値 (文字列)
  • 型判定
    • isinstance【インスタンス判定】:str【文字列型】と判定されるので問題なし
    • type【型クラス】:enum【列挙型】と判定されるので、str【文字列型】に変換が必要

メンバ参照

所属・演算・比較

その他


StrEnum 例:使用方法

from enum import StrEnum, unique

@unique
class StrColor(StrEnum):
    RED = 'Red'
    GREEN = 'Green'
    BLUE = 'Blue'
    GRAY = 'Gray'
    COLOR_ETC = b'Color\x80Etc', 'utf-8', 'backslashreplace'
    # GREY = GRAY
    # ValueError: duplicate values found in <enum 'StrColor'>: GREY -> GRAY

    def print_details(self):
        print(self, self.name, self.value, sep=' / ')


# メンバ参照
for mem in StrColor:
    mem.print_details()
# 出力
# Red / RED / Red
# Green / GREEN / Green
# Blue / BLUE / Blue
# Gray / GRAY / Gray
# Color\x80Etc / COLOR_ETC / Color\x80Etc

StrEnum 例:互換性

from enum import Enum, StrEnum

# strとEnum 継承
class StrColorUser(str, Enum):
    RED = 'Red'
    GREEN = 'Green'
    BLUE = 'Blue'
print(StrColorUser.RED)
# 出力:StrColorUser.RED
print(f'{StrColorUser.BLUE}')
# 出力:StrColorUser.BLUE

# StrEnum 継承
class StrColor(StrEnum):
    RED = 'Red'
    GREEN = 'Green'
    BLUE = 'Blue'
print(StrColor.RED)
# 出力:Red
print(f'{StrColor.BLUE}')
# 出力:Blue

# 型チェック
s = 'Black'
print(isinstance(s, str))
# 出力:True
print(isinstance(StrColor.RED, str))
# 出力:True
print(isinstance(StrColorUser.RED, str))
# 出力:True

print(type(s))
# 出力:<class 'str'>
print(type(StrColor.BLUE))
# 出力:<enum 'StrColor'>
print(type(str(StrColor.BLUE)))
# 出力:<class 'str'>
print(type(StrColorUser.BLUE))
# 出力:<enum 'StrColorUser'>
print(type(str(StrColorUser.BLUE)))
# 出力:<class 'str'>

StrEnum 例:値の自動定義

from enum import StrEnum, auto

class StrColor(StrEnum):
    RED = auto()
    GREEN = auto()
    BLUE = auto()

for mem in StrColor:
    print(mem)
# 出力
# red
# green
# blue

class StrColorUSer(StrEnum):
    @staticmethod
    def _generate_next_value_(name, start, count, last_values):
        print(f'{name=} {start=} {count=} {last_values=}')
        return 'COLOR_' + name
    RED = auto()
    GREEN = auto()
    BLUE = auto()
# 出力
# name='RED' start=1 count=0 last_values=[]
# name='GREEN' start=1 count=1 last_values=['COLOR_RED']
# name='BLUE' start=1 count=2 last_values=['COLOR_RED', 'COLOR_GREEN']

for mem in StrColorUSer:
    print(mem)
# 出力
# COLOR_RED
# COLOR_GREEN
# COLOR_BLUE

StrEnum 例:制約指定

from enum import StrEnum, unique, verify, UNIQUE

# 別名有効 (デフォルト)
class StrColor(StrEnum):
    GRAY = 'Gray'
    GREY = GRAY  # 別名

# @unique【一意値】
@unique
class StrColorA(StrEnum):
    GRAY = 'Gray'
    # GREY = GRAY  # 例外
    # ValueError: duplicate values found in <enum 'StrColorA'>: GREY -> GRAY

# @verify(UNIQUE)【一意値】
@verify(UNIQUE)
class StrColorB(StrEnum):
    GRAY = 'Gray'
    # GREY = GRAY  # 例外
    # ValueError: aliases found in <enum 'StrColorB'>: GREY -> GRAY

# _order_【定義順】
class StrEnumOrderA(StrEnum):
    _order_ = 'MEM_A MEM_B'
    MEM_A = 'MemberA'
    MEM_B = 'MemberB'

class StrEnumOrderB(StrEnum):
    # _order_ = 'MEM_B MEM_A'  # 例外
    MEM_A = 'MemberA'
    MEM_B = 'MemberB'
# TypeError: member order does not match _order_:
#   ['MEM_A', 'MEM_B']
#   ['MEM_B', 'MEM_A']

StrEnum 例:メンバ参照

from enum import StrEnum

class StringEnum(StrEnum):
    MEM_A = 'MemberA'
    MEM_B = 'MemberB'
    MEM_C = 'MemberC'
    MEM_X = MEM_A  # 別名

# EnumType.__len__(cls)【メンバ数】len(列挙型)
print(len(StringEnum))
# 出力:3

# EnumType.__iter__(cls)【イテレータ (列挙型)】
# EnumType.__reversed__(cls)【逆順】
for mem in StringEnum:
    print(mem)
# 出力
# MemberA
# MemberB
# MemberC
for mem in reversed(StringEnum):
    print(mem)
# 出力
# MemberC
# MemberB
# MemberA
print(list(StringEnum))
# 出力:[<StringEnum.MEM_A: 'MemberA'>, <StringEnum.MEM_B: 'MemberB'>, <StringEnum.MEM_C: 'MemberC'>]
print(list(reversed(StringEnum)))
# 出力:[<StringEnum.MEM_C: 'MemberC'>, <StringEnum.MEM_B: 'MemberB'>, <StringEnum.MEM_A: 'MemberA'>]
print([mem.name for mem in StringEnum])
# 出力:['MEM_A', 'MEM_B', 'MEM_C']
print([mem.value for mem in StringEnum])
# 出力:['MemberA', 'MemberB', 'MemberC']
print([(mem.name, mem.value) for mem in StringEnum])
# 出力:[('MEM_A', 'MemberA'), ('MEM_B', 'MemberB'), ('MEM_C', 'MemberC')]

# __members__【全メンバ列挙】
for name, mem in StringEnum.__members__.items():
    print(name, mem, sep=' / ')
# 出力
# MEM_A / MemberA
# MEM_B / MemberB
# MEM_C / MemberC
# MEM_X / MemberA
print([(name, mem.value) for name, mem in StringEnum.__members__.items()])
# 出力:[('MEM_A', 'MemberA'), ('MEM_B', 'MemberB'), ('MEM_C', 'MemberC'), ('MEM_X', 'MemberA')]
print([name for name, mem in StringEnum.__members__.items()])
# 出力:['MEM_A', 'MEM_B', 'MEM_C', 'MEM_X']
print([mem.value for name, mem in StringEnum.__members__.items()])
# 出力:['MemberA', 'MemberB', 'MemberC', 'MemberA']
# 別名
alias = [name for name, mem in StringEnum.__members__.items() if mem.name != name]
print(alias)
# 出力:['MEM_X']

# EnumType.__getitem__(cls)【名前アクセス】enumtype['メンバ名']
lst = ['MEM_A', 'MEM_B', 'MEM_C', 'MEM_X', 'MEM_XYZ']
for name in lst:
    print(name, StringEnum[name], sep=' / ')
# 出力
# MEM_A / MemberA
# MEM_B / MemberB
# MEM_C / MemberC
# MEM_X / MemberA
# 例外:KeyError: 'MEM_XYZ'

# EnumType.__call__(cls)【値アクセス】enumtype(メンバ値)
lst = ['MemberA', 'MemberB', 'MemberC', 'MemberX']
for value in lst:
    print(f'{value} / ', end='')
    print(StringEnum(value))
# 出力
# MemberA / MemberA
# MemberB / MemberB
# MemberC / MemberC
# MemberX /
# 例外:ValueError: 'MemberX' is not a valid ~

# Enum._missing_(cls)【未検索処理】
class StringEnumMissing(StrEnum):
    MEM_NON = 'None'
    MEM_A = 'MemberA'

    @classmethod
    def _missing_(cls, value):
        print(f'_missing_({cls}, {value})')
        return cls.MEM_NON

print(StringEnumMissing('MemberA'))
# 出力:MemberA
print(StringEnumMissing('MemberX'))
# 出力
# _missing_(<enum 'StringEnumMissing'>, MemberX)
# None

StrEnum 例:所属・比較

from enum import StrEnum

class StringEnum(StrEnum):
    MEM_A = 'MemberA'
    MEM_B = 'MemberB'
    MEM_C = 'MemberC'
    MEM_X = MEM_A  # 別名

# EnumType.__contains__(cls)【所属判定 (列挙型)】(メンバ | メンバ値) in 列挙型
print(StringEnum.MEM_A in StringEnum)
# 出力:True
print(StringEnum.MEM_B in StringEnum)
# 出力:True
print(StringEnum.MEM_C in StringEnum)
# 出力:True
print(StringEnum.MEM_X in StringEnum)
# 出力:True
print('MemberA' in StringEnum)
# 出力:True
print('MemberB' in StringEnum)
# 出力:True
print('MemberC' in StringEnum)
# 出力:True
print('MemberX' in StringEnum)
# 出力:False
print('MemberX' not in StringEnum)
# 出力:True

# 演算
s1 = 'Start_' + StringEnum.MEM_C + '_End'
print(s1)
# 出力:Start_MemberC_End
s2 = StringEnum.MEM_C * 3
print(s2)
# 出力:MemberCMemberCMemberC
print(StringEnum.MEM_C, len(StringEnum.MEM_C))
# 出力:MemberC 7

# is・is not【同一性比較】
class StringEnumCheck(StrEnum):
    MEM_A = 'MemberA'

print(StringEnum.MEM_A is StringEnum.MEM_A)
# 出力:True
print(StringEnum.MEM_A is StringEnum.MEM_X)
# 出力:True
print(StringEnum.MEM_A is not StringEnum.MEM_B)
# 出力:True
print(StringEnum.MEM_A is not StringEnumCheck.MEM_A)
# 出力:True

# ==・!=【等価比較】
print(StringEnum.MEM_A == StringEnum.MEM_A)
# 出力:True
print(StringEnum.MEM_A == StringEnum.MEM_X)
# 出力:True
print(StringEnum.MEM_A != StringEnum.MEM_B)
# 出力:True
print(StringEnum.MEM_A == StringEnumCheck.MEM_A)
# 出力:True
print(StringEnum.MEM_A == 'MemberA')
# 出力:True

# 大小比較
print(StringEnum.MEM_A < StringEnum.MEM_B < StringEnum.MEM_C)
# 出力:True
print(StringEnumCheck.MEM_A < StringEnum.MEM_B < 'MemberZ')
# 出力:True