メタプログラミングruby2章のdynamic-dispathの例をpythonで
pythonでやってみました。なかなか綺麗にならない><
- Source
- これはテスト用のdummyクラス
- Computer
- 件のクラス(メタプログラミング)
code
__init__より下にある関数は全部__init__のローカル関数。types.MethodTypeを使ってコンストラクタを実行時にインスタンスメソッドを生成。
## metaprograming ruby chapter2. class Source: def get_cpu_info(self, id): return "cpu" def get_mouse_info(self, id): return "mouse" def get_keyboard_info(self, id): return "keyboard" def get_cpu_price(self, id): return 100 def get_mouse_price(self, id): return 20 def get_keyboard_price(self, id): return 20 class Computer: def __init__(self, computer_id, data_source): self.id = computer_id self.data_source = data_source import re rx = re.compile(r"^get_(.*)_info$") def _getter_iter(): for name in data_source.__class__.__dict__.keys(): m = rx.search(name) if m: yield m.group(1) def _make_inspect(name): def _send(obj, mtd, *args): method = getattr(obj, mtd, None) if method is not None: return method(*args) def _inspect(self, id): info = _send(self.data_source,"get_%s_info" % name, self.id) price = _send(self.data_source,"get_%s_price" % name, self.id) result = "%s: %s (%s)" % (name.capitalize(), info, price) if price > 100: return "* %s" % result return result import types return types.MethodType(_inspect, self, Computer) for getter in _getter_iter(): self.__dict__[getter] = _make_inspect(getter) ########### data_source = Source() com = Computer(1, data_source) print com.keyboard(0) print com.cpu(0) print com.mouse(0)
output
Keyboard: keyboard (20) Cpu: cpu (100) Mouse: mouse (20)