Python Enum
Enumすら思い出せない忘れんぼさんなんで PythonのEnum を弄ってみました
列挙型定義
from enum import Enum class Colors(Enum): RED = '1' BLUE = 2 GREEN = 'green' print(Colors) # <enum 'Colors'>
動的に
>>> Enum('Colors', (('RED', '1'), ('BLUE', 2), ('GREEN', 'green'))) <enum 'Colors'>
Enum型の一覧
>>> Colors.__members__ mappingproxy(OrderedDict([('RED', <Colors.RED: '1'>), ('BLUE', <Colors.BLUE: 2>), ('GREEN', <Colors.GREEN: 'green'>)]))
名前、値を得る
>>> Colors.RED <Colors.RED: '1'> >>> Colors['RED'] <Colors.RED: '1'> >>> Colors.RED.name 'RED' >>> Colors.RED.value '1'
iterを当てるとgeneratorが返る
>>> iter(Colors) <generator object <genexpr> at 0x108b12120> >>> >>> (Colors.__members__[name] for name in Colors.__members__) <generator object <genexpr> at 0x108b12438> >>> >>> for color in Colors: ... print(repr(color)) ... <Colors.RED: 1> <Colors.BLUE: 2> <Colors.GREEN: 3>
定義後はClass, Attributeは削除できない
>>> del Colors.RED Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: RED >>> >>> del Colors.RED.name Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/python/lib/python3.4/enum.py", line 29, in __delete__ raise AttributeError("can't delete attribute") AttributeError: can`t delete attribute >>> >>> del Colors.RED.value Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/python/lib/python3.4/enum.py", line 29, in __delete__ raise AttributeError("can't delete attribute") AttributeError: can`t delete attribute
辞書のキーとして使う、Enumの比較
__hash__が定義されてたので辞書のキーでも使えた
>>> red1 = Colors.RED >>> dct = {red1: 10} >>> dct[red1] 10 >>> red2 = Colors.RED >>> dct[red2] 10 >>> red1 == red2 True
Pickle化
__getnewargs__ がある, pickleable みたい
>>> from pickle import dumps, loads >>> Colors.RED == loads(dumps(Colors.RED)) True
Enumの型を指定して扱う
Enumは定義時に型を指定すると列挙する値が、すべて指定した型になる
strとして列挙したい場合
from enum import Enum class Colors(str, Enum): RED = '1' BLUE = 2 GREEN = 'green' print(repr(Colors.BLUE)) # <Colors.BLUE: '2'> print(repr(Colors.BLUE.value)) # '2'
intとして列挙したい場合
IntEnumが用意されている
下記では 'green'
がエラーになる
from enum import IntEnum class Colors(IntEnum): RED = '1' BLUE = 2 GREEN = 'green' # ValueError: invalid literal for int() with base 10: 'green'
isdigitな数値ならOKのようだ、isnumericはだめ(IVとか, 四とか)
from enum import Enum class Colors(int, Enum): RED = '1' BLUE = 2 GREEN = b'3' YELLOW = '4' print(repr(Colors.GREEN.value)) # 3 print(repr(Colors.YELLOW.value)) # 4
floatとして列挙したい場合
from enum import Enum class Colors(float, Enum): RED = '1' BLUE = 2 GREEN = b'3' YELLOW = '4' print(repr(Colors.GREEN.value)) # 3.0 print(repr(Colors.YELLOW.value)) # 4.0
tupleとして列挙したい場合
もちろんtupleもある
from enum import Enum class Colors(tuple, Enum): RED = (1, 'red color') BLUE = (2, 'blue color') GREEN = (3, 'green color') print(repr(Colors.RED)) # <Colors.RED: (1, 'red color')> print(repr(Colors.RED.value)) # (1, 'red color')
NamedInt
class Colors(NamedInt, Enum): RED = ('red color', 1) BLUE = ('blue color', 2) GREEN = ('green color', 3) print(repr(Colors.RED)) # <Colors.RED: NamedInt('red color', 1)> print(repr(Colors.RED.value)) # NamedInt('red color', 1)
OrderedEnum
Eum同士の比較が可能
class Colors(OrderedEnum, Enum): RED = 1 BLUE = 2 GREEN = 3 print(Colors.RED < Colors.BLUE) # True
class Colors(Enum): RED = 1 BLUE = 2 GREEN = 3 print(Colors.RED < Colors.BLUE) # TypeError: unorderable types: Colors() < Colors()
LabelledIntEnum
class LabelledIntEnum(int, Enum): def __new__(cls, *args): value, label = args obj = int.__new__(cls, value) obj.label = label obj._value_ = value return obj class Colors(LabelledIntEnum): RED = (1, "red") BLUE = (2, "blue") GREEN = (3, "green") print(repr(list(Colors))) # [<Colors.RED: 1>, <Colors.BLUE: 2>, <Colors.GREEN: 3>] print(repr(Colors(1))) # <Colors.RED: 1> print(repr(Colors.RED)) # <Colors.RED: 1> print(repr(Colors.RED.value)) # 1
UniqueEnum
下のuniqueデコレーターと同じかな
列挙する値のユニークを保証する
uniqueデコレーターがありました。つかいませう
from enum import ( Enum, unique ) @unique class Colors(int, Enum): RED = '1' BLUE = 2 GREEN = '3' YELLOW = '3' # ValueError: duplicate values found in <enum 'Colors'>: YELLOW -> GREEN
自動採番
値がなければナンバリングされる
int
>>> Enum('Colors', ('RED', 'BLUE', 'GREEN', ), module=__name__).RED <Colors.RED: 1>
>>> Enum('Colors', 'RED BLUE GREEN').RED <Colors.RED: 1>
str
>>> StrEnum('Colors', 'RED BLUE GREEN').RED <Colors.RED: '1'>
tuple
>>> TupleEnum('Colors', 'RED BLUE GREEN').RED <Colors.RED: (1,)>
AutoNumberInAList
class AutoNumberInAList(Enum): def __new__(cls): value = [len(cls.__members__) + 1] obj = object.__new__(cls) obj._value_ = value return obj class Colors(AutoNumberInAList): RED = () BLUE = () GREEN = () print(repr(Colors.RED)) # <Colors.RED: [1]> print(repr(Colors.RED.value)) # [1]
AutoNumber
定義時に自動採番
auto_enum
定義時のmetaclassで自動採番
終わり
Enumには夢が詰まっているとのこと