Diary?

2009-09-06
Sun

(00:48)

最近ちょっと仕事し過ぎであまり日記を書いていなかったので、久しぶりに軽めの Python ネタ。今回は Python で引数の型に応じたディスパッチ、というか普通オーバーロードと呼ばれることをやってみる。殆ど出オチのようなコードなので、解説は一切しない。

class Dispatcher(property):
    def __init__(self):
        property.__init__(self, lambda obj: lambda fst, *args, **kwds: self.execute(obj, fst, *args, **kwds))
        self.func_map = {}
    
    def __call__(self, t):
        if t in self.func_map:
            raise DispatchError(str(t))
        def _make_map(f):
            self.func_map[t] = f
            return f
        return _make_map
    
    def execute(self, obj, fst, *args, **kwds):
        fun = None
        for t, f in self.func_map.iteritems():
            if isinstance(fst, t):
                fun = f
                break
        if not fun:
            raise DispatchError('Can not dispatch to %s' % (str(t)))
        return fun(obj, fst, *args, **kwds)
    
class DispatchError(Exception):
    pass

使い方はこう。

class Foo(object):
    foo = Dispatcher()
    @foo(int)
    def ifoo(self, i):
        print '%d is integer' % i
    
    @foo(str)
    def sfoo(self, s):
        print '%s is string' % s

コードとしての見どころは property を継承しているところと、その property の getter としてλ式を渡し、そのλ式がディスパッチしたいメソッドの所属するオブジェクトを受け取り、そこからさらに Dispatcher の execute メソッドが呼ばれているところ。あとデコレータが None を返してるので個々の振り分け先のメソッドが隠蔽されてるところは、多分だけど実際には隠蔽しない方がいい。

だからどうしたという気がしなくもないが、思いついちゃったものは仕方がない。

(17:27)

そういや最近あんまりギターの練習もできてなかったなあと思ったので、リハビリがてら Paradise Lost の Shattered をコピーしてみた。リズムがよれてるのはいつもの事なので気にしない。ヴォーカルの出来が酷いのも(以下略)。本当はグロウルする曲じゃないんだけど、低音がどうしても出なかったのでごまかす事にした。いや、あんまごまかせてないけど。

ミキシングに関しては、ちょっとドラムが奥に引っ込みすぎた気がしないでもない。あとリードギターがやかましいかも。

Creative Commons
この怪文書はクリエイティブ・コモンズ・ライセンスの元でライセンスされています。引用した文章など Kuwata Chikara に著作権のないものについては、それらの著作権保持者に帰属します。