背景
簡易なプログラムを書く際、わざわざデータベースを立てたり設定ファイルから定数を取得するのも面倒な時は、データをプログラムにハードコーディングしてしまう場合もしばしばあります。
ただ、この場合もできるだけスマートに書きたいですよね。そこで自分が調べたり検証した内容をまとめます。
結論として、Enumを使うといい感じに書けます。
なお、ほとんど公式ドキュメントに書かれている内容です。
https://docs.python.org/ja/3/library/enum.html
シンプルなEnum
PythonのEnumはClassとして定義します。
列挙型は読み書きが容易になるよう class 文を使って作成します。もうひとつの作成方法は 機能 API で説明しています。列挙型は以下のように Enum のサブクラスとして定義します:
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
if __name__ == "__main__":
print(Color.RED)
print(Color.GREEN)
print(Color.BLUE)
1
2
3
Enumにフィールドをもたせる
Enumのメンバー値以外に値をもたせたい場合があります。
例えば日本語名とか。
そういった場合はコンストラクタで値を設定します。
from enum import Enum
class Color(Enum):
RED = (1, '赤')
GREEN = (2, '緑')
BLUE = (3, '青')
def __init__(self, id, ja):
self.id = id
self.ja = ja
if __name__ == "__main__":
print('#=== ja ===#')
print(Color.RED.ja)
print(Color.GREEN.ja)
print(Color.BLUE.ja)
#=== ja ===#
赤
緑
青
なお、Enumのメンバー値はintに限らず何でも良いです。
メンバー値は何であっても構いません: int, str などなど。 正確な値が重要でない場合は、 auto インスタンスを使っておくと、適切な値が選ばれます。 auto とそれ以外の値を混ぜて使う場合は注意する必要があります。
ここでのメンバー値はvalueの値の通りになってます。
Enumにメソッドやプロパティをもたせる
全メンバーを取得したり、メソッドやプロパティも持たせたくなりますね。
from enum import Enum
class Color(Enum):
RED = (1, '赤')
GREEN = (2, '緑')
BLUE = (3, '青')
def __init__(self, id, ja):
self.id = id
self.ja = ja
# tagとしてidとjaを連結した文字列を取得する
@property
def tag(self):
return "{}_{}".format(self.id, self.ja)
# 全メンバーを取得する
@classmethod
def members_as_list(cls):
# Order dictionary -> list
return [*cls.__members__.values()]
# idを指定して取得する
@classmethod
def get_by_id(cls, id):
for c in cls.members_as_list():
if id == c.id:
return c
# default
return Color.RED
if __name__ == "__main__":
print('#=== members ===#')
print(Color.members_as_list())
print('#=== enum ===#')
for c in Color.get_all():
print(c)
print('#=== ja ===#')
for c in Color.get_all():
print(c.ja)
print('#=== id ===#')
for c in Color.get_all():
print(c.id)
print('#=== tag ===#')
for c in Color.get_all():
print(c.tag)
#=== all ===#
[<Color.RED: (1, '赤')>, <Color.GREEN: (2, '緑')>, <Color.BLUE: (3, '青')>]
#=== enum ===#
Color.RED
Color.GREEN
Color.BLUE
#=== ja ===#
赤
緑
青
#=== id ===#
1
2
3
#=== tag ===#
1_赤
2_緑
3_青
いかがでしたか?
結構色々できて便利ですね!
ただし書き方が独特で慣れるまで大変そうです。