14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Python】Enumでvalue以外のkeyでも値を取得する方法

Last updated at Posted at 2020-02-23

Enumでvalue以外のkeyでも値を取得する方法

はじめに

多くのプログラミング言語にはEnumというものがあります。Pythonにも同様にあります。メンバーの取得はそれぞれのvalueをkeyに取得できますが、それ以外の値をkeyにすることはできません。通常のEnumを拡張すればできたので紹介します。

通常のEnumの確認

まずは通常のEnumの利用方法を確認します。

>>> from enum import Enum
>>>
>>> class Color(Enum):
...     RED = 1
...     GREEN = 2
...     BLUE = 3

# 上記のようにEnumを宣言すると
# 1や2といったvalueをkeyにして各メンバーにアクセスできます

>>> color = Color(1)
>>> print(color)
Color.RED

# もちろん直接アクセスすることもできます
>>> print(Color.RED)
Color.RED
>>> print(color == Color.RED)
True

やりたいこと

Color(1)Color.REDにアクセスできましたがたとえばColor('red')Color('赤')でもアクセスできたらEnumの可能性が広がります。

>>> from enum import Enum
>>>
>>> class Color(Enum):
...     RED = 1
...     GREEN = 2
...     BLUE = 3

# 以下のようにアクセスしようとするともちろんエラーになる
>>> color = Color('red')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/local/lib/python3.6/enum.py", line 293, in __call__
    return cls.__new__(cls, value)
  File "/usr/local/lib/python3.6/enum.py", line 535, in __new__
    return cls._missing_(value)
  File "/usr/local/lib/python3.6/enum.py", line 548, in _missing_
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 'red' is not a valid Color

>>> color = Color('')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/local/lib/python3.6/enum.py", line 293, in __call__
    return cls.__new__(cls, value)
  File "/usr/local/lib/python3.6/enum.py", line 535, in __new__
    return cls._missing_(value)
  File "/usr/local/lib/python3.6/enum.py", line 548, in _missing_
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: '' is not a valid Color

実装

ではkeyを拡張したEnumの実装を確認します。

# 宣言時に以下のように`_value2member_map_`を更新する
>>> from enum import Enum
>>>
>>> class Color(Enum):
...     def __new__(cls, value, en, ja):
...         obj = object.__new__(cls)
...         obj._value_ = value
...         cls._value2member_map_.update({en: obj, ja: obj})
...         return obj
...     RED = (1, 'red', '')
...     GREEN = (2, 'green', '')
...     BLUE = (3, 'blue', '')

# これで先程のように'red'や'赤'でアクセスすると
>>> color = Color('red')
>>> print(color)
Color.RED

>>> red = Color('')
>>> print(red)
Color.RED

最後に

やりすぎるとkeyがかぶったりする可能性もありますが、知っておいて損はないと思います。
DBではint型、APIではstr型とかで使えそうです。

14
6
0

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
14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?