Python データ型:ユーティリティとデコレータ(列挙型)をマスターしよう!


列挙型とは何ですか?

列挙型は、固定された値の集合を表す特殊なデータ型です。各値は、名前対応する値を持ちます。列挙型は、プログラムで使用される定数を明確かつ簡潔に定義するために使用されます。

列挙型の利点

列挙型を使用する利点は次のとおりです。

  • バグの削減: 列挙型を使用すると、誤った値の使用を防ぐことができ、バグを減らすことができます。
  • 保守性の向上: 列挙型を使用すると、コードをより簡単に保守することができます。
  • 理解しやすさの向上: 列挙型を使用すると、コードの意味をより簡単に理解することができます。
  • 可読性の向上: プログラムで使用される定数を明確に定義することで、コードが読みやすくなります。

列挙型の作成

列挙型は、enum モジュールを使用して作成できます。次の例は、曜日を表す列挙型を作成する方法を示しています。

from enum import Enum

class Day(Enum):
    MONDAY = 1
    TUESDAY = 2
    WEDNESDAY = 3
    THURSDAY = 4
    FRIDAY = 5
    SATURDAY = 6
    SUNDAY = 7

この例では、Day という名前の列挙型が定義されています。この列挙型には、MONDAYTUESDAYWEDNESDAY など、7 つのメンバーがあります。各メンバーには、1 から 7 までの値が割り当てられています。

列挙型の使用

列挙型を使用するには、まず列挙型クラスからメンバーをインポートする必要があります。次の例は、Day 列挙型から MONDAY メンバーをインポートする方法を示しています。

from enum import Enum

class Day(Enum):
    MONDAY = 1
    TUESDAY = 2
    WEDNESDAY = 3
    THURSDAY = 4
    FRIDAY = 5
    SATURDAY = 6
    SUNDAY = 7

today = Day.MONDAY
print(today)

この例では、Day.MONDAY メンバーが today 変数に割り当てられています。print(today) ステートメントは、MONDAY メンバーの値である 1 を出力します。

列挙型のメンバーは、条件式やスイッチステートメントで使用することもできます。次の例は、Day 列挙型のメンバーを使用して、曜日ごとに異なるメッセージを出力する方法を示しています。

from enum import Enum

class Day(Enum):
    MONDAY = 1
    TUESDAY = 2
    WEDNESDAY = 3
    THURSDAY = 4
    FRIDAY = 5
    SATURDAY = 6
    SUNDAY = 7

today = Day.MONDAY

if today == Day.MONDAY:
    print("今日は月曜日です。")
elif today == Day.TUESDAY:
    print("今日は火曜日です。")
elif today == Day.WEDNESDAY:
    print("今日は水曜日です。")
elif today == Day.THURSDAY:
    print("今日は木曜日です。")
elif today == Day.FRIDAY:
    print("今日は金曜日です。")
elif today == Day.SATURDAY:
    print("今日は土曜日です。")
else:
    print("今日は日曜日です。")

列挙型ユーティリティ

enum モジュールには、列挙型を操作するためのいくつかのユーティリティ関数があります。次の表に、最も一般的なユーティリティ関数をいくつか示します。

関数説明
hasattr(enum_class, name)列挙型クラスに name という名前のメンバーがあるかどうかを確認します。
getattr(enum_class, name)列挙型クラスから name という名前のメンバーを取得します。
list(enum_class)列挙型クラスのすべてのメンバーのリストを返します。
member(enum_class, value)指定された値を持つ列挙型メンバーを返します。
trymember(enum_class, value)指定された値を持つ列挙型メンバーを返そうとし、見つからない場合は ValueError をスローします。


from enum import Enum, auto

class Color(Enum):
    RED = auto()
    GREEN = auto()
    BLUE = auto()

class Shape(Enum):
    CIRCLE = 1
    SQUARE = 2
    TRIANGLE = 3

def get_color_name(color):
    if color == Color.RED:
        return "赤"
    elif color == Color.GREEN:
        return "緑"
    elif color == Color.BLUE:
        return "青"
    else:
        return "不明な色"

def get_shape_name(shape):
    if shape == Shape.CIRCLE:
        return "円形"
    elif shape == Shape.SQUARE:
        return "方形"
    elif shape == Shape.TRIANGLE:
        return "三角形"
    else:
        return "不明な形状"

# 色と形状の列挙型メンバーをインスタンス化
red_color = Color.RED
square_shape = Shape.SQUARE

# 列挙型メンバーの値にアクセス
print(red_color.value)  # 1 を出力
print(square_shape.name)  # "SQUARE" を出力

# 列挙型メンバーをユーティリティ関数に渡す
print(get_color_name(red_color))  # "赤" を出力
print(get_shape_name(square_shape))  # "方形" を出力

この例では、ColorShape という 2 つの列挙型が定義されています。Color 列挙型には、REDGREENBLUE という 3 つのメンバーがあります。Shape 列挙型には、CIRCLESQUARETRIANGLE という 3 つのメンバーがあります。

get_color_name 関数は、Color 列挙型メンバーを受け取り、その色の名前を返します。get_shape_name 関数は、Shape 列挙型メンバーを受け取り、その形状の名前を返します。

例では、red_colorsquare_shape 変数に、Color.REDShape.SQUARE の列挙型メンバーが割り当てられます。次に、これらのメンバーの値にアクセスし、ユーティリティ関数に渡します。

この例は、Pythonにおける列挙型の基本的な使用方法を示しています。列挙型は、プログラムで使用される定数を明確かつ簡潔に定義するために使用できます。これにより、コードが読みやすく、理解しやすく、保守しやすくなります。

  • Enum.trymember(value) メソッドは、指定された値を持つ列挙型メンバーを返そうとし、見つからない場合は ValueError をスローします。
  • Enum.member(value) メソッドは、指定された値を持つ列挙型メンバーを返します。
  • Enum.__values__ 属性は、列挙型クラスのすべてのメンバーの値のリストを返します。
  • Enum.__members__ 属性は、列挙型クラスのすべてのメンバーの辞書を返します。
  • auto() 修飾子は、列挙型メンバーの値を自動的に生成するために使用されます。これにより、各メンバーに手動で値を割り当てる必要がなくなります。


列挙型メンバーにメタデータを追加する

列挙型メンバーにメタデータを追加するには、@property デコレータと @enum.unique デコレータを使用します。次の例は、Color 列挙型にメタデータを追加する方法を示しています。

from enum import Enum, auto, unique

@unique
class Color(Enum):
    RED = auto(rgb=(255, 0, 0))
    GREEN = auto(rgb=(0, 255, 0))
    BLUE = auto(rgb=(0, 0, 255))

def get_rgb_color(color):
    return color.rgb

red_color = Color.RED
print(get_rgb_color(red_color))  # (255, 0, 0) を出力

この例では、@unique デコレータを使用して、Color 列挙型に unique 制約を追加しています。これにより、列挙型には同じ値を持つメンバーが 2 つ以上存在しないことが保証されます。

Color 列挙型メンバーには、rgb という名前の @property デコレータ付きメソッドが定義されています。このメソッドは、メンバーの RGB 色値を返します。

get_rgb_color 関数は、Color 列挙型メンバーを受け取り、そのメンバーの RGB 色値を返します。

列挙型からフラグを作成する

列挙型からフラグを作成するには、IntFlag ベースクラスを使用します。次の例は、曜日を表すフラグ列挙型を作成する方法を示しています。

from enum import Enum, IntFlag

class Day(IntFlag):
    MONDAY = 1 << 0
    TUESDAY = 1 << 1
    WEDNESDAY = 1 << 2
    THURSDAY = 1 << 3
    FRIDAY = 1 << 4
    SATURDAY = 1 << 5
    SUNDAY = 1 << 6

weekend = Day.SATURDAY | Day.SUNDAY
print(weekend.value)  # 64 を出力

weekend 変数には、SATURDAYSUNDAY のメンバーのビットワイズ OR が割り当てられています。これにより、weekend 変数の値は 64 になります。

列挙型をサブクラス化するには、Enum ベースクラスを使用します。次の例は、Color 列挙型のサブクラスである PrimaryColor 列挙型を作成する方法を示しています。

from enum import Enum, auto

class Color(Enum):
    RED = auto()
    GREEN = auto()
    BLUE = auto()

class PrimaryColor(Color):
    RED = auto()
    BLUE = auto()

red_color = PrimaryColor.RED
print(red_color)  # PrimaryColor.RED を出力

この例では、PrimaryColor という名前の列挙型が定義されています。この列挙型は、Color 列挙型のサブクラスです。PrimaryColor 列挙型には、REDBLUE の 2 つのメンバーがあります。