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
メモ
概要
- 言語組み込みの列挙型ではなく、 標準ライブラリの enum【列挙型モジュール】3.4 として提供
- 以下の列挙型を提供
- Enum【列挙型 (基本クラス)】3.6~3.7 / 3.113.12 ( EnumType【列挙型メタクラス】3.113.12 )
- IntEnum【列挙型 (整数)】3.11
- Flag【列挙型 (ビットフラグ)】3.63.11
- IntFlag【列挙型 (整数ビットフラグ)】3.63.11
- StrEnum【列挙型 (文字列)】3.11
使用方法
- 各列挙型のサブクラスとして使用 (但し、一般的なクラスとは相違)〔詳細は各列挙型参照〕
- メソッド定義可:他の言語は不可
- 関数でも作成可:EnumType.__call__【関数呼び出し作成】
- メンバ名は定数として全て大文字推奨 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 範囲外値の制御 (Flag・IntFlag 用)
(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:連続値で欠損値不可 (Enum・IntEnum で有効)
・NAMED_FLAGS:複数ビットの組み合わせは、単独ビットの定義が必要 (Flag・IntFlag で有効)
関連
外部リンク
例:継承・独自列挙型
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 )
メモ
概要
- Enum【列挙型 (基本クラス)】のメタクラス
- 名前変更:EnumMeta も別名として存続3.11
- サブクラス化可能
メソッド
メソッド | 備考 |
---|---|
__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制御 範囲外の値処理 (Flag・IntFlagで使用) |
__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【名前リスト・属性リスト】 |
__getitem__( cls (列挙型), name) | 名前アクセス〔例:各列挙型参照〕 enumtype['メンバ名'] メンバ (列挙子) name検索メンバ名 KeyError 例外該当なし |
__iter__(cls (列挙型)) | イテレータ (列挙型)〔例:各列挙型参照〕 ・別名は対象外 ・Flag・IntFlag のビットなし・複数ビットも対象外 3.11 関連:Flag.__iter__(self)【イテレータ (列挙子:ビットフラグ)】 |
__len__(cls (列挙型)) | メンバ数〔例:各列挙型参照〕 len(列挙型) ・別名は対象外 ・Flag・IntFlag のビットなし・複数ビットも対象外 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【列挙型メタクラス】
- 既存コードで互換性を考慮する場合、IntEnum【列挙型 (整数)】を使用
- 列挙子
- 値は任意
- 別名可 (デフォルト)
使用方法
〔 例 〕- Enum【列挙型 (基本クラス)】のサブクラスを定義し、メンバを指定
- メンバ名:Enum.name【メンバ名】属性
- メンバ値:Enum.value【メンバ値】属性
- 関数でも作成可:__call__【関数呼び出し作成】参照〔 例 〕
- 必要に応じて制約を指定:制約指定 参照
- メソッド定義可
- メンバの動的作成:_ignore_【無視リスト】参照〔 例 〕
値の自動定義
〔 例 〕- auto【値自動取得】を値として定義
- 1 から増加
- 即値と混在:最後の値に 1 を加えた値
- _generate_next_value_【auto カスタマイズ】 のオーバーライドで変更可3.6
制約指定
〔 例 〕- 一意値
- 連続値
- 定義順
- _order_【定義順】3.6
メンバ参照
〔 例 〕- メンバ数:len(cls) (参照:EnumType.__len__(cls)【メンバ数】)
- 別名:対象外
- イテレータ (列挙型):EnumType.__iter__(cls)【イテレータ (列挙型)】
- 別名:対象外
- reversed(Enum)で逆順:EnumType.__reversed__(cls)【逆順】
- 全メンバ列挙:__members__【全メンバ列挙】
- 別名:対象
- 名前アクセス
- Enum['メンバ名']:EnumType.__getitem__【名前アクセス】
- 値アクセス
- Enum(値):EnumType.__call__【値アクセス】
- Enum._missing_(cls)【未検索処理】でメンバ値の未検索処理の変更可
所属・比較
〔 例 〕- 所属
- EnumType.__contains__(cls)【所属判定 (列挙型)】:(メンバ | メンバ値3.12 ) in 列挙型
- 比較
- is・is not:同一性比較
- ==・!=:等価比較 (非列挙型の値とは不等)
- >等:大小比較不可 (値にして比較)
その他
関連
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
メモ
概要
- 整数値の列挙型
- 既存コードの整数値との互換を考慮 (互換性参照)
- int【整数型】とReprEnum【文字列変換】(Enum【列挙型 (基本クラス)】を継承)のサブクラス
- 新規コードでは、Enum【列挙型 (基本クラス)】が適当
- 列挙子
- 値は整数値
- 別名可 (デフォルト)
使用方法
〔 例 〕- IntEnum【列挙型 (整数)】のサブクラスを定義し、メンバを指定
- 指定値は int【整数型】のコンストラクタに引き渡し
- メンバ名:Enum.name【メンバ名】属性
- メンバ値:Enum.value【メンバ値】属性
- 関数でも作成可 (__call__【関数呼び出し作成】参照)
- 必要に応じて制約を指定:制約指定 参照
- メソッド定義可
- メンバの動的作成:_ignore_【無視リスト】参照
値の自動定義
〔 例 〕- auto【値自動取得】を値として定義
- 1 から増加
- 即値と混在:最後の値に 1 を加えた値
- _generate_next_value_【auto カスタマイズ】 のオーバーライドで変更可3.6
制約指定
〔 例 〕- 一意値
- 連続値
- 定義順
- _order_【定義順】3.6
互換性
〔 例 〕- 整数値からの置換が容易になるように、以下の仕様
- __str__:メンバ値 (整数値) 3.11
- __format__:メンバ値 (整数値)
- 型判定
- isinstance【インスタンス判定】:int【整数型】と判定されるので問題なし
- type【型クラス】:enum【列挙型】と判定されるので、int【整数型】に変換が必要
メンバ参照
〔 例 〕- メンバ数:len(cls) (参照:EnumType.__len__(cls)【メンバ数】)
- 別名:対象外
- イテレータ (列挙型):EnumType.__iter__(cls)【イテレータ (列挙型)】
- 別名:対象外
- reversed(IntEnum)で逆順:EnumType.__reversed__(cls)【逆順】
- 全メンバ列挙:__members__【全メンバ列挙】
- 別名:対象
- 名前アクセス
- IntEnum['メンバ名']:EnumType.__getitem__【名前アクセス】
- 値アクセス
- IntEnum(値):EnumType.__call__【値アクセス】
- Enum._missing_(cls)【未検索処理】でメンバ値の未検索処理の変更可
所属・演算・比較
〔 例 〕- 所属
- EnumType.__contains__(cls)【所属判定 (列挙型)】:(メンバ | メンバ値3.12 ) in 列挙型
- 演算
- 整数演算可 (結果:列挙型ではない)
- 比較
- 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 | メンバ定義がないビットフラグの数値フォーマット関数 |
概要
- ビットフラグ値の列挙型
- 既存コードで互換性を考慮する場合、IntFlag【列挙型 (整数ビットフラグ)】を使用
- 値
- 基本は単独ビットフラグ 3.11
- ビットフラグなし (0)は特殊値
- 複数ビットフラグ可 (デフォルト)
- 別名可 (デフォルト)
- Enum【列挙型 (基本クラス)】のサブクラス
- ビット関連の演算結果もFlag【列挙型 (ビットフラグ)】
使用方法
〔 例 〕- Flag のサブクラスを定義し、メンバを指定
- メンバ名:Enum.name【メンバ名】属性
- メンバ値:Enum.value【メンバ値】属性
- 関数でも作成可:EnumType.__call__【関数呼び出し作成】参照
- 必要に応じて制約を指定:制約指定 参照
- メソッド定義可
- メンバの動的作成:Enum._ignore_【無視リスト】参照
値の自動定義
〔 例 〕- auto【値自動取得】を値として定義
- 1 から始まる 2 の累乗
- 即値と混在:最大値より大きい最初の 2 のべき乗
- _generate_next_value_【auto カスタマイズ】 のオーバーライドで変更可3.6
制約指定
〔 例 〕- 一意値
- 複数ビットの組み合わせ
- @verify(NAMED_FLAGS)【制約検証 デコレータ】 (単独ビットの定義が必要)
- 範囲外の値
- 定義順
- _order_【定義順】3.6
メンバ参照
〔 例 〕- メンバ数:len(cls) (参照:EnumType.__len__(cls)【メンバ数】)
- 別名:対象外
- ビットフラグなし (0):対象外
- 複数ビットフラグ:対象外 3.11
- ビットフラグ数 3.11:Flag.__len__(self)【ビットフラグ数】
- イテレータ (列挙型):EnumType.__iter__(cls)【イテレータ (列挙型)】
- 別名:対象外
- ビットフラグなし (0):対象外
- 複数ビットフラグ:対象外 3.11
- reversed(Flag)で逆順:EnumType.__reversed__(cls)【逆順】
- 全メンバ列挙:__members__【全メンバ列挙】
- 別名:対象
- ビットフラグなし (0):対象
- 複数ビットフラグ:対象
- イテレータ (列挙子:ビットフラグ) 3.11:Flag.__iter__(self)【イテレータ (列挙子:ビットフラグ)】
- 名前アクセス
- Flag['メンバ名']:EnumType.__getitem__【名前アクセス】
- 値アクセス
- Flag(値):EnumType.__call__【値アクセス】
- ビットフラグなし (0) は特殊値
- Enum._missing_(cls)【未検索処理】でメンバ値の未検索処理の変更可
所属・演算・比較
〔 例 〕- 所属
- (メンバ | メンバ値3.12 ) in 列挙型:EnumType.__contains__(cls)【所属判定 (列挙型)】
- 列挙子 in 列挙子:Flag.__contains__(self)【所属判定 (列挙子:ビットフラグ)】
- ビットフラグ演算 (FlagBoundary【範囲外値の制御】 参照)
- 比較
- is・is not:同一性比較
- ==・!=:等価比較 (非列挙型の値とは不等)
- >等:大小比較不可 (値にして比較)
その他
関連
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
メモ
概要
- 整数ビットフラグ値の列挙型
- 既存コードの整数ビットフラグ値との互換を考慮 (互換性参照)
- 新規コードでは、Flag【列挙型 (ビットフラグ)】が適当
- 値
- 基本は単独ビットフラグ 3.11
- ビットフラグなし (0)は特殊値
- 複数ビットフラグ可 (デフォルト)
- 別名可 (デフォルト)
- int【整数型】とReprEnum【文字列変換】(Enum【列挙型 (基本クラス)】を継承)とFlag【列挙型 (ビットフラグ)】のサブクラス
- ビット関連の演算結果は整数
使用方法
〔 例 〕- IntFlag のサブクラスを定義し、メンバを指定
- 指定値は int【整数型】のコンストラクタに引き渡し
- メンバ名:Enum.name【メンバ名】属性
- メンバ値:Enum.value【メンバ値】属性
- 関数でも作成可:EnumType.__call__【関数呼び出し作成】参照
- 必要に応じて制約を指定:制約指定 参照
- メソッド定義可
- メンバの動的作成:Enum._ignore_【無視リスト】参照
互換性
〔 例 〕- 整数値からの置換が容易になるように、以下の仕様
- __str__:
メンバメンバ値 (整数値) 3.11- int.__str__() を使用 (ReprEnum【文字列変換】) 3.11
- __format__:メンバ値 (整数値)
- __str__:
- 型判定
- isinstance【インスタンス判定】:int【整数型】と判定されるので問題なし
- type【型クラス】:enum【列挙型】と判定されるので、int【整数型】に変換が必要
値の自動定義
〔 例 〕- auto【値自動取得】を値として定義
- 1 から始まる 2 の累乗
- 即値と混在:最大値より大きい最初の 2 のべき乗
- _generate_next_value_【auto カスタマイズ】 のオーバーライドで変更可3.6
制約指定
〔 例 〕- 一意値
- 複数ビットの組み合わせ
- @verify(NAMED_FLAGS)【制約検証 デコレータ】 (単独ビットの定義が必要)
- 範囲外の値
- 定義順
- _order_【定義順】3.6
メンバ参照
〔 例 〕- メンバ数:len(cls) (参照:EnumType.__len__(cls)【メンバ数】)
- 別名:対象外
- ビットフラグなし (0):対象外
- 複数ビットフラグ:対象外 3.11
- ビットフラグ数 3.11:Flag.__len__(self)【ビットフラグ数】
- イテレータ (列挙型):EnumType.__iter__(cls)【イテレータ (列挙型)】
- 別名:対象外
- ビットフラグなし (0):対象外
- 複数ビットフラグ:対象外 3.11
- reversed(IntFlag)で逆順:EnumType.__reversed__(cls)【逆順】
- 全メンバ列挙:__members__【全メンバ列挙】
- 別名:対象
- ビットフラグなし (0):対象
- 複数ビットフラグ:対象
- イテレータ (列挙子:ビットフラグ) 3.11:Flag.__iter__(self)【イテレータ (列挙子:ビットフラグ)】
- 名前アクセス
- IntFlag['メンバ名']:EnumType.__getitem__【名前アクセス】
- 値アクセス
- IntFlag(値):EnumType.__call__【値アクセス】
- ビットフラグなし (0) は特殊値
- Enum._missing_(cls)【未検索処理】でメンバ値の未検索処理の変更可
所属・演算・比較
〔 例 〕- 所属
- (メンバ | メンバ値3.12 ) in 列挙型:EnumType.__contains__(cls)【所属判定 (列挙型)】
- 列挙子 in 列挙子:Flag.__contains__(self)【所属判定 (列挙子:ビットフラグ)】
- ビットフラグ演算 (FlagBoundary【範囲外値の制御】 参照)
- 比較
- is・is not:同一性比較
- ==・!=:等価比較 (値で比較)
- >等:大小比較 (値で比較)
その他
関連
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【文字列型】とReprEnum【文字列変換】(Enum【列挙型 (基本クラス)】を継承)のサブクラス
- 列挙子
- 値は文字列のみ有効 (指定値はstr【文字列型】のコンストラクタに引き渡し)
- 別名可 (デフォルト)
使用方法
〔 例 〕- StrEnum【列挙型 (文字列)】のサブクラスを定義し、メンバを指定
- メンバ名:Enum.name【メンバ名】属性
- メンバ値:Enum.value【メンバ値】属性
- 関数でも作成可:EnumType.__call__【関数呼び出し作成】参照
- 必要に応じて制約を指定:制約指定 参照
- メソッド定義可
- メンバの動的作成:Enum._ignore_【無視リスト】参照
値の自動定義
〔 例 〕- auto【値自動取得】を値として定義
- 小文字のメンバ名
- _generate_next_value_【auto カスタマイズ】 のオーバーライドで変更可3.6
制約指定
〔 例 〕- 一意値
- 定義順
- _order_【定義順】3.6
互換性
〔 例 〕- 既存文字列の置換を考慮し、以下の仕様
(str【文字列型】とEnum【列挙型 (基本クラス)】の継承とは相違)- __str__:メンバ値 (文字列)
- __format__:メンバ値 (文字列)
- 型判定
- isinstance【インスタンス判定】:str【文字列型】と判定されるので問題なし
- type【型クラス】:enum【列挙型】と判定されるので、str【文字列型】に変換が必要
メンバ参照
〔 例 〕- メンバ数:len(cls) (参照:EnumType.__len__(cls)【メンバ数】)
- 別名:対象外
- イテレータ (列挙型):EnumType.__iter__(cls)【イテレータ (列挙型)】
- 別名:対象外
- reversed(StrEnum)で逆順:EnumType.__reversed__(cls)【逆順】
- 全メンバ列挙:__members__【全メンバ列挙】
- 別名:対象
- 名前アクセス
- StrEnum['メンバ名']:EnumType.__getitem__【名前アクセス】
- 値アクセス
- StrEnum(値):EnumType.__call__【値アクセス】
- Enum._missing_(cls)【未検索処理】でメンバ値の未検索処理の変更可
所属・演算・比較
〔 例 〕- 所属
- (メンバ | メンバ値3.12 ) in 列挙型:EnumType.__contains__(cls)【所属判定 (列挙型)】
- 演算
- str【文字列型】の演算可
- 比較
- is・is not:同一性比較
- ==・!=:等価比較 (値で比較)
- >等:大小比較 (値で比較)
その他
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