LoginSignup
18
20

More than 3 years have passed since last update.

【Python】Enumで静的データ管理

Last updated at Posted at 2019-09-02

背景

簡易なプログラムを書く際、わざわざデータベースを立てたり設定ファイルから定数を取得するのも面倒な時は、データをプログラムにハードコーディングしてしまう場合もしばしばあります。
ただ、この場合もできるだけスマートに書きたいですよね。そこで自分が調べたり検証した内容をまとめます。
結論として、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_青

いかがでしたか?
結構色々できて便利ですね!
ただし書き方が独特で慣れるまで大変そうです。

参考

enum --- 列挙型のサポート
要素数 どのようにpython enumクラスからすべての値を取得するには?

18
20
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
20