Enum
Pythonで列挙体を生成するユーティリティ関数作ってみた。
コンパイル時に型チェックしない言語/環境では、
その恩恵を受けられないため軽視されがちだけど。
値の生成だけでも欲しくなった。ここでは名前のリストを渡して、
値が適当に重複しない値になっていれば充分。程度の需要なので。
# 動機)wxPythonで リソースID を列挙するのが面倒だった。
from __future__ import nested_scopes # for python2.1 from types import ListType def enum_factory(func, enum, start): if type(enum) is not ListType: raise TypeError else: map(func, enum, range(start, start+len(enum))) def import_enum_with_prefix(package, prefix, enum, start=0): import_enum(package, map(lambda s:prefix+s, enum), start) def import_enum(package, enum, start=0): def set_enum(k, v): package[k] = v enum_factory(set_enum, enum, start) def create_enum_class(enum, start=0): class _Enum_Class: pass enum_factory(lambda k,v:setattr(_Enum_Class,k,v), enum, start) return _Enum_Class def create_enum_object(enum, start=0): return create_enum_class(enum, start)() if __name__ == '__main__': enum = ["NAME", "TREE"] import_enum_with_prefix(locals(), "ID_", enum, 1) print ID_MENU print ID_TREE obj = create_enum_object(enum, 1) print obj.MENU print obj.TREE class EnumClass(create_enum_class(enum, 1)): def menu(self): print self.MENU def tree(self): print self.TREE obj = EnumClass() obj.menu() obj.tree()
考察:
- ID_MENU_FOO_BAR と、globals()もしくはlocals() に読み込んでしまうと、名前空間の汚染が心配。prefix付けてれば安全だけど、でもdir() したときにエントリがたくさん表れてしまうのは読みにくい。
- 辞書を作る。ID["MENU_FOO_BAR"] は、打つのが面倒。[" "]
- クラスに閉じ込める。ID.MENU_FOO_BARと表記。