プログラミングの話

python3.4のenumでちょっとハマった話

enumとは

列挙型ってやつらしいです。 python3.4から使えるらしいです。

使い方

インポートして直接利用する方法

第一引数を定義名、第二引数をリストか空白区切りの文字列としEnumの要素とする

以下の方法だと、Aって言うEnum型の定義名にBとCと言う要素を宣言した形となる

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from enum import Enum

hoge = Enum('A',['B','C'])

if __name__ == 'main':
    for tmp in hoge:
        print(tmp.name)
        print(tmp.value)

#出力
#B
#1
#C
#2
    print(hoge.B)
# A.B

インポートして、Enumを継承して利用する方法

先ほどとはちょっと異なる定義をします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from enum import Enum

class Hoge(Enum):
    A='a'
    B='b'

if __name__ == 'main':
    for tmp in Hoge:
        print(tmp.name)
        print(tmp.value)

#出力
#A
#a
#B
#b
    print(Hoge.A)
#出力
#Hoge.A

何にハマったか

keyとvalueのシンプルな関係を持たせることが出来るなら、正誤表みたいな使い方が連想配列の代わりにEnumで出来るな!と考えて以下の様な定義と使い方をしてみました。

1
2
3
4
5
6
7
8
9
10
11
from Enum import enum

class Hoge(Enum):
    A=True
    B=False
    C=True

if __name__ == 'main':
    for tmp in Hoge:
        print(tmp.name)
        print(tmp.value)

すると結果は

1
2
3
4
5
#出力
#A
#True
#B
#False

何故かCが定義されてない。

なぜ定義されていないか

ドキュメントにきちんと書いてありました。

ただし、複数の列挙型メンバーが同じ値を持つことはできます。同じ値を持つ 2 つのメンバー A および B (先に定義したのは A) が与えられたとき、B は A の別名になります。A および B を値で調べたとき、A が返されます。B を名前で調べたとき、A が返されます:

つまり、同じ値を持っているものは同じ名前だよね?って処理がされます。

上の例ではAとCが両方TrueなのでCの定義はAと同義とみなされたということです。

wikipediaの列挙型のページを見る限りいくつかの定数の集まりとして使うのが正解なのでしょうかね?

列挙型を使うのが初めてで存じ上げませんでした。

ドキュメントをきちんと読まなかったので、ちょっとだけハマった話でした。