2019-04-17に更新

PythonのEnumのvalueの設定にはauto()をつかい、検索にはEnumのnameを使うのが良い

Python3.4ぐらいから導入されて、3.6ぐらいからまともに使えるようになったEnumとかいうのがある。
* https://docs.python.org/ja/3/library/enum.html

Enumが便利なのは、その名の通り、明示的に値を列挙するので、利用可能な値を確実に表現することができる。例えば、利用可能な値として色を表現するときには以下のようにできる。

from enum import Enum

class Color(Enum):
    red = "red"
    blue = "blue"
    green = "green"

このように定義すれば、

>>> print(Color.red)
Color.red

と記述できるので、コードの表現力が高くなるし、通常、ただの定数などで"red"と書く場合に比べて圧倒的にタイポしにくい(IDEなどによる補完が期待できるので)。

で、ある値が上のように定義したColorの中に含まれているかを探したいときがある。その場合、値はEnumの値ではなく名前を使って検索したほうが良い。この辺の感覚、普段からちゃんと(?)Enumを使っていればわかるんだけど、Enumはドキュメントにも書かれているように

列挙型は、一意の定数値に束縛された識別名 (メンバー) の集合

なので、確実に一意が約束されているのは値ではなく名前のほう。なので、以下のように定義することができるため、

from enum import Enum

class Color(Enum):
    red = "ao"
    blue = "ao"
    green = "midori"

以下のような事故が起きる可能性がある。

>>> # Color.blueを探したい
>>> for c in Color:
>>>     if c.value == "ao":
>>>         print(c)

Color.red

また、Enumの値は重複させることができるので、そもそも値で検索しても一意が保証されない。よって、Enumを利用するときはちゃんと名前を利用すること。そうすれば、ある値がEnumの中で定義されているかどうかは簡単に見つけることができる。

>>> # ちゃんとnameで検索すること
>>> "blue" in Color.__members__
True

ということで、値を設定しない場合はenum.auto()が使えるので、コーディング規約として、特別な理由がない限りはEnumに値を設定しないことにしたほうが良さそう。

from enum import Enum, auto
class Color(Enum):
    red = auto()  # 上から連番が振られる
    blue = auto()
    gree = auto()

shige

Crieitは個人で開発中です。 興味がある方は是非記事の投稿をお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください!

ボードとは?

関連記事

コメント