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 列挙型
(整数以外も可)
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 )
ユニーク デコレータ〔
同じ値の別名定義不可
操作EnumFlagIntEnumIntFlag
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'>]