enum【列挙型モジュール】3.43.63.5~3.7
Enum【列挙型】3.4
Flag【ビットフラグ列挙型】3.6
IntEnum【整数列挙型】3.4
IntFlag【整数ビットフラグ列挙型】3.6
メモ ( 概要 使用方法 例 イテレーション 例 比較・操作 例 ) クラス ( 属性 デコレータ 操作) 例 (auto【値自動取得】のカスタマイズ )
メモ
Python 3.10
- Python 3.10 で予定されていた変更は、全て Python 3.11 に持ち越し
概要
- 言語組み込みの列挙子ではなく、 標準ライブラリの enum【列挙型】3.4 として提供
- 下記の特殊クラスが存在
- Enum【列挙型】3.4
- Flag【ビットフラグ列挙型】3.6
- IntEnum【整数列挙型】3.4
- IntFlag【整数ビットフラグ列挙型】3.6
- StrEnum【文字列列挙型】3.11
- デフォルトの開始番号:C++等の 0 ではなく 1 (詳細は メンバ評価 参照)
- プライベート名は使用不可 (DeprecationWarning 例外)
使用可 3.11
使用方法
〔 例 〕- 提供クラスのサブクラスとして使用 (但し、一般的なクラスとは相違)
- 定数として全て大文字推奨 3.6
- 別名で同じ値の定義可 (@unique【ユニーク デコレータ】指定で別名不可)
- 値:auto【値自動取得】3.6 の指定可 (オーバーライド可)
イテレーション
〔 例 〕- 定義順
- 別名は除外 (__members__【全メンバ列挙】 は別名を含む)
- 名前・値の参照:name【名前】属性・value【値】属性
比較・操作
〔 例 〕- 基本形は別の型との比較は偽 (値が同じ整数値でも同様)
- 整数値との比較が必要な場合、 IntEnum【整数列挙型】 ・IntFlag【整数ビットフラグ列挙型】3.6 を使用
- その他操作:操作一覧 参照
関連
外部リンク
- Python 標準ライブラリ
enum --- 列挙型のサポート - 通常のクラスとの違いについては、 Enum はどう違うのか? 参照
- 機能 API については、 機能 API 参照
- int【整数型】以外の派生列挙型の作成可 (詳細は、 派生列挙型 - その他 参照)
- 特殊用途に適用するには、 興味深い例 参照
クラス
クラス | 備考 |
---|---|
Enum 3.4 | 列挙型 (整数以外も可) |
Flag 3.6 | ビットフラグ列挙型 注:str【文字列型】等を定義可能だが、他のメンバもビット演算不可 |
IntEnum 3.4 | 整数列挙型 (整数との比較可:既存システムとの互換等で使用) |
IntFlag 3.6 | 整数ビットフラグ列挙型 (整数との比較可:既存システムとの互換等で使用) |
auto 3.6 | 値の自動取得 (※:デフォルトで整数値を順に返却するが、仕様上は不定) 下記でオーバーライド可 (メンバの前に定義)〔 例 〕 _generate_next_value_(name, start, count, last_values) 戻り値設定値 name定義名 start開始値 count定義数 last_values定義メンバ |
属性〔 例 〕 | 備考 |
---|---|
name | 名前 |
value | 値 |
__members__ | 全メンバ列挙 (順序保持・別名含む) (名前・列挙型メンバのマッピング) |
メソッド・デコレータ | 備考 |
---|---|
unique() ( @unique ) | ユニーク デコレータ〔 例 〕 同じ値の別名定義不可 |
操作 | Enum | Flag | IntEnum | IntFlag | |
---|---|---|---|---|---|
enum['名前'] | 名前アクセス | ● | |||
enum(値) | 値アクセス | ● | |||
is is not | 同一性比較 | ● | |||
== != | 等価比較 | ● | ● int【整数型】とは値で比較 | ||
> 等 | 値順序比較 | TypeError 例外 | ● 整数値として比較 | ||
&【ビット論理積】 |【ビット論理和】 ^【ビット排他的論理和】 ~【1の補数】 | メンバ間の ビット演算 | TypeError 例外 | ● Flag | ● int【整数型】に変換 | ● IntFlag |
メンバ以外の ビット演算 | TypeError 例外 | TypeError 例外 | ● int【整数型】に変換 | ● IntFlag | |
bool | メンバ評価 | True ※ | False:値が 0 True:その他 |
※:値が 0 (False 相当) でもメンバであれば True〔 例 〕
(値が 0 だと紛らわしい為、デフォルトの開始番号は 1)
例
使用方法
# Enum【列挙型】
from enum import Enum, auto, unique
class Align(Enum):
LEFT = auto()
CENTER = auto()
RIGHT = auto()
DEFAULT = CENTER # 別名
UNKNOWN = "Unknown" # 別の型
@unique
class AlignUnique(Enum):
LEFT = auto()
CENTER = auto()
RIGHT = auto()
# DEFAULT = CENTER # 別名
# 例外:ValueError
print(list(Align))
# 出力:[<Align.LEFT: 1>, <Align.CENTER: 2>, <Align.RIGHT: 3>, <Align.UNKNOWN: 'Unknown'>]
print(list(AlignUnique))
# 出力:[<AlignUnique.LEFT: 1>, <AlignUnique.CENTER: 2>, <AlignUnique.RIGHT: 3>]
align_1 = Align.CENTER
print(align_1, align_1.name, align_1.value)
# 出力:Align.CENTER CENTER 2
align_2 = Align.DEFAULT
print(align_2, align_2.name, align_2.value)
# 出力:Align.CENTER CENTER 2
align_9 = AlignUnique.CENTER
print(align_9, align_9.name, align_9.value)
# 出力:AlignUnique.CENTER CENTER 2
# Flag【ビットフラグ列挙型】
from enum import Flag, auto, unique
class Mode(Flag):
ENABLED = auto()
HIDDEN = auto()
READONLY = auto()
REQUIRED = auto()
DEFAULT = ENABLED # 別名
@unique
class ModeUnique(Flag):
ENABLED = auto()
HIDDEN = auto()
READONLY = auto()
REQUIRED = auto()
# DEFAULT = ENABLED # 別名
# 例外:ValueError
print(list(Mode))
# 出力:[<Mode.ENABLED: 1>, <Mode.HIDDEN: 2>, <Mode.READONLY: 4>, <Mode.REQUIRED: 8>]
print(list(ModeUnique))
# 出力:[<ModeUnique.ENABLED: 1>, <ModeUnique.HIDDEN: 2>, <ModeUnique.READONLY: 4>, <ModeUnique.REQUIRED: 8>]
mode_1 = Mode.ENABLED
print(mode_1, mode_1.name, mode_1.value)
# 出力:Mode.ENABLED ENABLED 1
mode_2 = Mode.DEFAULT
print(mode_2, mode_2.name, mode_2.value)
# 出力:Mode.ENABLED ENABLED 1
mode_9 = ModeUnique.ENABLED
print(mode_9, mode_9.name, mode_9.value)
# 出力:ModeUnique.ENABLED ENABLED 1
# IntEnum【整数列挙型】
from enum import IntEnum
class Color(IntEnum):
RED = 0xFF0000
GREEN = 0x00FF00
BLUE = 0x0000FF
WHITE = 0xFFFFFF
DEFAULT = RED # 別名
# UNKNOWN = "Unknown" # int型以外
# 例外:ValueError
def getRGB(self):
r = self.value >> 16
g = (self.value & 0x00FF00) >> 8
b = self.value & 0x0000FF
return r, g, b
for item in Color:
print(f"{item.name:5} {item.value:#08x}")
# 出力:RED 0xff0000
# 出力:GREEN 0x00ff00
# 出力:BLUE 0x0000ff
# 出力:WHITE 0xffffff
color_1 = Color.GREEN
print(color_1, color_1.getRGB())
# 出力:Color.GREEN (0, 255, 0)
color_2 = Color.WHITE
print(color_2, color_2.getRGB())
# 出力:Color.WHITE (255, 255, 255)
# IntFlag【整数ビットフラグ列挙型】
from enum import IntFlag
class Bit(IntFlag):
# Position (0b__PP)
POS_FIRST = 0b01
POS_MIDDLE = 0b10
POS_LAST = 0b11
POS_MASK = 0b11
# Mode (0bMM__)
MODE_OFF = 0
MODE_ON = 0b0100
MODE_RESERVE = 0b1000
MODE_RESET = 0b1100
MODE_MASK = 0b1100
# UNKNOWN = "Unknown" # int型以外
# 例外:ValueError
def getPos(self):
pos = self.value & self.POS_MASK
return pos
def getModifyPos(self, pos):
modify = (self.value & ~self.POS_MASK) | pos
return modify
def getMode(self):
mode = self.value & self.MODE_MASK
return mode
def getModifyMode(self, mode):
modify = (self.value & ~self.MODE_MASK) | mode
return modify
for item in Bit:
print(f"{item.name:12} {item.value:#06b}")
# 出力:POS_FIRST 0b0001
# 出力:POS_MIDDLE 0b0010
# 出力:POS_LAST 0b0011
# 出力:MODE_OFF 0b0000
# 出力:MODE_ON 0b0100
# 出力:MODE_RESERVE 0b1000
# 出力:MODE_RESET 0b1100
bit_1 = Bit(0b1111)
print(type(bit_1))
# 出力:<enum 'Bit'>
print(bit_1)
# 出力:Bit.MODE_RESET|MODE_RESERVE|MODE_ON|POS_LAST|POS_MIDDLE|POS_FIRST
print(bit_1.getPos(), bit_1.getMode())
# 出力:Bit.POS_LAST Bit.MODE_RESET
bit_2 = Bit.POS_FIRST | Bit.MODE_ON
print(type(bit_2))
# 出力:<enum 'Bit'>
print(bit_2.getPos(), bit_2.getMode())
# 出力:Bit.POS_FIRST Bit.MODE_ON
bit_3 = bit_2.getModifyPos(Bit.POS_MIDDLE)
print(bit_3.getPos(), bit_3.getMode())
# 出力:Bit.POS_MIDDLE Bit.MODE_ON
bit_3 = bit_3.getModifyMode(Bit.MODE_RESET)
print(bit_3.getPos(), bit_3.getMode())
# 出力:Bit.POS_MIDDLE Bit.MODE_RESET
print(type(bit_3))
# 出力:<enum 'Bit'>
イテレーション
from enum import Enum, Flag, auto
class Color(Enum):
RED = auto()
GREEN = auto()
BLUE = auto()
DEFAULT = RED # 別名
for item in Color:
print(item.name, item.value)
# 出力:RED 1
# 出力:GREEN 2
# 出力:BLUE 3
for name, member in Color.__members__.items():
print(name, member.value)
# 出力:RED 1
# 出力:GREEN 2
# 出力:BLUE 3
# 出力:DEFAULT 1
class Mode(Flag):
ENABLED = auto()
HIDDEN = auto()
READONLY = auto()
DEFAULT = ENABLED # 別名
for item in Mode:
print(item.name, item.value)
# 出力:ENABLED 1
# 出力:HIDDEN 2
# 出力:READONLY 4
for name, member in Mode.__members__.items():
print(name, member.value)
# 出力:ENABLED 1
# 出力:HIDDEN 2
# 出力:READONLY 4
# 出力:DEFAULT 1
比較・操作
# Enum【列挙型】・IntEnum【整数列挙型】
from enum import Enum, IntEnum
class Color(Enum):
RED = 0xFF0000
GREEN = 0x00FF00
BLUE = 0x0000FF
BLACK = 0x000000
class IntColor(IntEnum):
RED = 0xFF0000
GREEN = 0x00FF00
BLUE = 0x0000FF
BLACK = 0x000000
# 名前アクセス
print(Color['RED'], IntColor['GREEN'])
# 出力:Color.RED IntColor.GREEN
# 値アクセス
print(Color(0x00FF00), IntColor(0x0000FF))
# 出力:Color.GREEN IntColor.BLUE
color_r = Color.RED
color_ir = IntColor.RED
# 同一性比較
print((color_r is Color.RED), (color_ir is IntColor.RED))
# 出力:True True
print((color_r is IntColor.RED), (color_ir is Color.RED))
# 出力:False False
print((color_r is not Color.RED), (color_ir is not IntColor.RED))
# 出力:False False
# 等価比較
print((color_r == Color.RED), (color_ir == IntColor.RED))
# 出力:True True
print((color_r != Color.RED), (color_ir != IntColor.RED))
# 出力:False False
print((color_r == Color.RED), (color_ir == Color.RED))
# 出力:True False
print((color_r == IntColor.RED), (color_ir == IntColor.RED))
# 出力:False True
print((color_r == 0xFF0000), (color_ir == 0xFF0000))
# 出力:False True
# 値順序比較
# print(color_r < Color.BLUE)
# 例外:TypeError
print(color_ir < IntColor.BLUE)
# 出力:False
# ビット演算 (メンバ間)
# color_new = color_r | Color.GREEN
# 例外:TypeError
color_inew = color_ir | IntColor.GREEN
print(f"{color_inew:#08x}", type(color_inew))
# 出力:0xffff00 <class 'int'>
# ビット演算 (メンバ以外)
# color_new = color_r | 0x0000FF
# 例外:TypeError
color_inew = color_ir | 0x0000FF
print(f"{color_inew:#08x}", type(color_inew))
# 出力:0xff00ff <class 'int'>
# メンバ評価
# ※デフォルトの開始番号を1とする理由
print(bool(color_r), bool(color_r.value), bool(color_ir), bool(color_ir.value))
# 出力:True True True True
color_b = Color.BLACK
color_ib = IntColor.BLACK
print(bool(color_b), bool(color_b.value), bool(color_ib), bool(color_ib.value))
# 出力:True False False False
# Flag【ビットフラグ列挙型】・IntFlag【整数ビットフラグ列挙型】
from enum import Flag, IntFlag
class Bit(Flag):
BIT_0 = 0b0001
BIT_1 = 0b0010
BIT_2 = 0b0100
BIT_3 = 0b1000
BIT_NONE = 0
class IntBit(IntFlag):
BIT_0 = 0b0001
BIT_1 = 0b0010
BIT_2 = 0b0100
BIT_3 = 0b1000
BIT_NONE = 0
# 名前アクセス
print(Bit['BIT_0'], IntBit['BIT_0'])
# 出力:Bit.BIT_0 IntBit.BIT_0
# 値アクセス
print(Bit(0b0100), IntBit(0b0100))
# 出力:Bit.BIT_2 IntBit.BIT_2
bit_1 = Bit.BIT_1
bit_i1 = IntBit.BIT_1
# 同一性比較
print((bit_1 is Bit.BIT_1), (bit_i1 is IntBit.BIT_1))
# 出力:True True
print((bit_1 is IntBit.BIT_1), (bit_i1 is Bit.BIT_1))
# 出力:False False
print((bit_1 is not Bit.BIT_1), (bit_i1 is not IntBit.BIT_1))
# 出力:False False
# 等価比較
print((bit_1 == Bit.BIT_1), (bit_i1 == IntBit.BIT_1))
# 出力:True True
print((bit_1 != Bit.BIT_1), (bit_i1 != IntBit.BIT_1))
# 出力:False False
print((bit_1 == IntBit.BIT_1), (bit_i1 == Bit.BIT_1))
# 出力:False False
print((bit_1 == 0b0010), (bit_i1 == 0b0010))
# 出力:False True
# 値順序比較
# print(bit_1 < Bit.BIT_2)
# 例外:TypeError
print(bit_i1 < IntBit.BIT_2)
# 出力:True
# ビット演算 (メンバ間)
bit_x = bit_1 | Bit.BIT_3
print(bit_x, type(bit_x))
# 出力:Bit.BIT_3|BIT_1 <enum 'Bit'>
bit_ix = bit_i1 | IntBit.BIT_3
print(bit_ix, type(bit_ix))
# 出力:IntBit.BIT_3|BIT_1 <enum 'IntBit'>
# ビット演算 (メンバ以外)
# bit_x = bit_1 | 0b10000000
# 例外:TypeError
bit_ix = bit_i1 | 0b10000000
print(bit_ix, type(bit_ix))
# 出力:IntBit.128|BIT_1 <enum 'IntBit'>
# メンバ評価
print(bool(bit_1), bool(bit_1.value), bool(bit_i1), bool(bit_i1.value))
# 出力:True True True True
bit_none = Bit.BIT_NONE
bit_inone = IntBit.BIT_NONE
print(bool(bit_none), bool(bit_none.value), bool(bit_inone), bool(bit_inone.value))
# 出力:False False False False
auto【値自動取得】のカスタマイズ
from enum import Enum, auto
# 通常動作
class Color(Enum):
RED = auto()
GREEN = "green"
BLUE = auto()
BLACK = auto()
print(list(Color))
# 出力:[<Color.RED: 1>, <Color.GREEN: 'green'>, <Color.BLUE: 2>, <Color.BLACK: 3>]
# 内部定義
class ColorA(Enum):
def _generate_next_value_(name, start, count, last_values):
print(f"_generate_...({name=}, {start=}, {count=}, {last_values=})")
return name
RED = auto()
GREEN = "green"
BLUE = auto()
BLACK = auto()
# 出力:_generate_...(name='RED', start=1, count=0, last_values=[])
# 出力:_generate_...(name='BLUE', start=1, count=2, last_values=['RED', 'green'])
# 出力:_generate_...(name='BLACK', start=1, count=3, last_values=['RED', 'green', 'BLUE'])
print(list(ColorA))
# 出力:[<ColorA.RED: 'RED'>, <ColorA.GREEN: 'green'>, <ColorA.BLUE: 'BLUE'>, <ColorA.BLACK: 'BLACK'>]
# 汎用定義
class UserAuto(Enum):
def _generate_next_value_(name, start, count, last_values):
print(f"_generate_...({name=}, {start=}, {count=}, {last_values=})")
return name
class ColorB(UserAuto):
RED = auto()
GREEN = "green"
BLUE = auto()
BLACK = auto()
# 出力:_generate_...(name='RED', start=1, count=0, last_values=[])
# 出力:_generate_...(name='BLUE', start=1, count=2, last_values=['RED', 'green'])
# 出力:_generate_...(name='BLACK', start=1, count=3, last_values=['RED', 'green', 'BLUE'])
print(list(ColorB))
# 出力:[<ColorB.RED: 'RED'>, <ColorB.GREEN: 'green'>, <ColorB.BLUE: 'BLUE'>, <ColorB.BLACK: 'BLACK'>]