14
11

More than 5 years have passed since last update.

enum を使わず列挙モドキを実現する

Last updated at Posted at 2015-02-01

以下のような変数定義をスマートにできないものかと、少し考えたのでメモまで。
「もっといい方法があるぜ」という方いたらコメントください。

STYLE_RED = 1
STYLE_BLUE = 2
STYLE_GREEN = 3
STYLE_YELLOW = 4
 :

「enum 使えよ」って話なんだけど、Python2.7系では標準ではenumは使えないので、なんとか小技を効かせて実現したい。
(Python2.7系向けに、enum34なるenum機能のバックポートも提供されている)

ポイント

こうした変数定義は、開発中に追加や削除を繰り返すことが多く、特に定義済みの変数の間に新しい定義を追加する場合に、後段の値もすべてずらさなければならないことが多々ある。

STYLE_RED = 1
SYTLE_BLACK = 2  # どうしてもここに 2 として追加したい
STYLE_BLUE = 3   # 後段の値をずらす
STYLE_GREEN = 4  # これも..
STYLE_YELLOW = 5 # これも...
 :

こうした追加/削除をサクッと行えるかどうかがポイント。

タプルを使う方法

こんな感じ。

(
    RED,
    BLUE,
    GREEN,
    YELLOW,
) = range(0, 4)

print 'Color RED: %d' % RED

個々に値を指定していないので、変数の追加でいちいちずらす必要はないが、range() 関数の第二引数も同時に変更する必要がある。

(
    RED,
    BLACK,  # 追加
    BLUE,
    GREEN,
    YELLOW,
) = range(0, 5)  # 4->5 に変更

タプルを使うことで、不変変数にもなるので、用途によっては非常に有用。
見た目もenum風だし、名前付きにすることで逐次処理を行うこともできる。

COLORS = (
    RED,
    BLUE,
      :
) = range(0, ...)

変数を使って値をインクリメントしながら代入

Pythonでは ++ 演算が使えないので、以下のような実装はできない。

int colorVal = 0
int RED = colorVal++;
int BLUE = colorVal++;
  :

これをPythonでやる場合、(おそらく) 以下のような形になる。

_cv = 0
RED = _cv = (_cv + 1)
BLUE = _cv = (_cv + 1)
GREEN = _cv = (_cv + 1)
YELLOW = _cv = (_cv + 1)

右辺が同じ表現なので、変数の追加は簡単に行える。
ただし、コードがどうにもスマートに見えないので、個人的にはタプルを使う方法がPythonらしくてよいと思う。(素直にenumを使うのが一番よい)

14
11
1

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
11