Python

【Python】列挙型を使う方法 【Enum・IntEnum】

この記事では、Pythonで列挙型を使う方法を解説します。

列挙型(Enum)とは、抽象データを定義するための機能で、性別などのマジックナンバーを使ってしまいそうな値を型として定義することができます。

例えば、以下のようなコードを見たことありませんか?

# 性別を表す変数
gender = 0

if gender == 0:
    print('男性')
else:
    print('女性')

上記のコードは、gender変数の値が「0ならば男性」「0以外ならば女性」と出力するコードですが、値自体にはなんの関連性も無く、人によっては「0 = 女性」「1 = 男性」「2 = その他」と定義するかもしれません。

そこで列挙型の出番です!

列挙型は、Python3.4 から追加されました

列挙型(Enum)を使う

列挙型は、enumモジュールのEnumクラスを継承させることで使うことができます。

先ほどの性別を列挙型にすると、以下のようになります。
※ 今回は分かりやすいように日本語で定義しました。

from enum import Enum

class Gender(Enum):
    男性 = 0
    女性 = 1

これでGenderという性別を表す列挙型が定義できました。

では、列挙型を用いて最初のコードを書き直してみましょう!
すると、以下のようになります。

gender = Gender.男性

if gender == Gender.男性:
    print('男性')
else:
    print('女性')

マジックナンバーを使わずに定義できて、とてもわかりやすいですね☺️

このように、列挙型を使うことで、抽象的な概念を型として定義することができます。

定義

列挙型は、以下のように定義します。

from enum import Enum

class クラス名(Enum):
    name1 = value1
    name2 = value2
          ・
          ・
          ・
    nameN = valueN

変数名がname、値がvalueとして扱われます。

呼び出し

次に、列挙型の呼び出し方法を見ていきましょう!

通常の呼び出し

print(Gender.男性)
# Gender.男性

nameのみの呼び出し

print(Gender.男性.name)
# 男性

valueのみの呼び出し

print(Gender.男性.value)
# 0

valueからの呼び出し

print(Gender(0))
# Gender.男性

for文を使った呼び出し

for g in Gender:
    print(g)

# Gender.男性
# Gender.女性

比較

列挙型は比較することが多いです。

==

print(Gender.男性 == Gender.男性)
# True
print(Gender.男性 == Gender.女性)
# False

!=

print(Gender.男性 != Gender.男性)
# False
print(Gender.男性 != Gender.女性)
# True

is

print(Gender.男性 is Gender.男性)
# True
print(Gender.男性 is Gender.女性)
# False

大なり小なり

print(Gender.男性 < Gender.男性)    # エラー
print(Gender.男性 > Gender.女性)    # エラー

数値との比較

数値と比較したいならIntEnumクラスを使う。

print(Gender.男性 == 0)
# False
print(Gender.女性 == 0)
# False

メソッド

通常のクラスと同様に列挙型には、メソッドを定義することもできます。呼び出し時にインスタンス化する必要はありません。

from enum import Enum

class Gender(Enum):
    男性 = 0
    女性 = 1

    # 列挙型のメソッド
    def get_name(self):
        return self.name

print(Gender.男性.get_name())
# 男性

print(Gender.女性.get_name())
# 女性

コンストラクタを定義することもできます。定義した場合は、列挙型の値がインスタンス変数に渡されます。

from enum import Enum

class Gender(Enum):
    男性 = 0
    女性 = 1

    # 列挙型のコンストラクタ
    def __init__(self, num):
        self.num = num

print(Gender.男性.num)
# 0
print(Gender.女性.num)
# 1

以下のように複数の値でも可能です。

from enum import Enum

class Test(Enum):
    NUMS1 = (0, 1, 2)
    NUMS2 = (3, 4, 5)

    def __init__(self, num1, num2, num3):
        self.num1 = num1
        self.num2 = num2
        self.num3 = num3


print(Test.NUMS1.num1)  # 0
print(Test.NUMS1.num2)  # 1
print(Test.NUMS1.num3)  # 2

print(Test.NUMS2.num1)  # 3
print(Test.NUMS2.num2)  # 4
print(Test.NUMS2.num3)  # 5

整数と比較できる列挙型[IntEnumクラス]

IntEnumクラスは、Enumクラスとほとんど変わりありませんが、整数と比較ができるようになっています。

from enum import IntEnum 

class Gender(IntEnum):
    男性 = 0
    女性 = 1


print(Gender.男性 == 0)
# True
print(Gender.女性 == 0)
# False

また、異なるIntEnum型とも比較可能です。

from enum import IntEnum

class Gender(IntEnum):
    男性 = 0
    女性 = 1

class Test(IntEnum):
    NUM1 = 0
    NUM2 = 1


print(Gender.男性 == Test.NUM1)
# True
print(Gender.男性 == Test.NUM2)
# False

さらに、Intが頭に付いているだけあって、整数として扱える場面が増えています。

print(int(Gender.男性))
# 0

nums = [1, 2, 3]
print(nums[Test.NUM1])
# 1

print(abs(Test.NUM1))
# 0

まとめ

この記事では、Pythonの列挙型の使い方について解説しました。

今回のおさらい
  • Enumクラスを継承して使う
  • 整数と比較したい場合はIntEnumクラスを使う

列挙型を使うことでマジックナンバーを減らすことができます。使える場面があったらじゃんじゃん使っていきましょう!

それでは今回の内容はここまでです!ではまたどこかで〜( ・∀・)ノ

最短3か月でエンジニア転職『DMM WEBCAMP COMMIT』