[Python] Enumクラスを拡張して使用する
はじめに
以前、Pythonで列挙型を使う場合について、下記の記事でまとめました。
今回は、Pythonで作成したEnumクラスに対して要素を追加したEnumクラスを拡張して作成するために、調べたことと、対応方法について、まとめていきます。
動作環境
windows11
Jupyter Notebook 6.5.2(Python 3.10.9)
やりたいこと
VegetablesというEnumクラスを定義しました。
from enum import Enum
class Vegetables(Enum):
Potato = 0
Onion = 1
Carrot = 2
このVegetablesクラスに対して、要素を追加したSummerVegetablesというクラスを作成したいと思います。
作成したEnumクラスを継承
作成したVegetablesクラスの継承して、下記のように実装しました。
class SummerVegetables(Vegetables):
corn = 4
Zucchini = 5
実行結果は、エラーです。
エラーの内容は、TypeError: SummerVegetables: cannot extend enumeration 'Vegetables'。Vegetablesを拡張できません…とのこと。
公式ドキュメントで、Enum型の記載内容を確認してみます。
Enumは、class文を使って定義を行うことができるが、は通常のクラスではないとの記載があります。
また、サブクラス化の制限として、スーパークラス側(今回だと、Vegetablesクラス)に要素が無い場合は、継承することができるようです。
実装して動作確認してみました。
class Vegetables(Enum):
pass
class SummerVegetables(Vegetables):
Corn = 4
Zucchini = 5
for kind in SummerVegetables:
print(kind, kind.value)
実行したところ、正常終了し、動作することはできました。
しかし、今回使用したいケースは、これには当てはまりません…
対応方法
対応方法は、下記のサイトを参考にしました。
関数として呼び出しできるということかな?と思い、ドキュメントを確認してみました。
Enumクラスのページ内に、機能APIというセクションを発見しました。
第1引数では、列挙型の名前を指定します。
第2引数では、列挙型のメンバー、名前、値に設定するデータを渡すことができます。
文字列
リスト
名前と値をペアにしたタプル
名前をキーに、値をバリューに設定した辞書
上記4つのうち、文字列、リストで渡す場合、名前を渡すこととなります。
これらの場合。値は、1から順に設定されます。
それでは、実装していきます。
summer_vegetables_value = {kind.name: kind.value for kind in Vegetables} | {'Corn': 4, 'Zucchini': 5}
SummerVegetables = Enum('SummerVegetables', summer_vegetables_value)
for kind in SummerVegetables:
print(kind,kind.value)
実行したところ、正常に動作することが確認できました!
コードの詳細について、順番に説明していきます。
辞書型の連結
拡張するEnumクラスのSummerVegetablesに対して名前、値に設定する、辞書型のデータを作成していきます。
EnumクラスのVegetablesから、名前と値を取得して辞書型に取得して設定し、追加で、SummerVegetablesに追加する名前、値を設定しています。
summer_vegetables_value = {kind.name: kind.value for kind in Vegetables} | {'Corn': 4, 'Zucchini': 5}
Python3.9以降、|演算子を使用して、辞書を連結することができるようになりました。
Python3.9以前のバージョンでは、**をつけてアンパックして辞書を連結します。
summer_vegetables_value = {
**{kind.name: kind.value for kind in Vegetables},
**{'Corn': 4,'Zucchini': 5}
}
Enumの機能APIを呼び出す
Enum関数を呼び出します。
第1引数として、列挙型の名前を、第2引数には、列挙型のメンバーを、名前、値として設定する辞書型を渡しています。
SummerVegetables = Enum('SummerVegetables', summer_vegetables_value)
まとめ
今回は、Pythonで作成したEnumクラスに対して要素を追加したEnumクラスを拡張する実装についてまとめました。