decoratorとかmemoizeとか

ふと python の decorator が気になってきていろいろ考える。@staticmethod って何やってるんだろうとか。

decoratorとは

decoratorってのは基本的には

@dec
def foo():
  pass

だったら

def foo():
  pass
foo = dec(foo)

しているだけだそうだから、要するにそういう関数をこねくれば良いのだよな。

staticmethodをミミック

def stm(f):
    return lambda self, *args: sys.stdout.write("my static method\n") or f(*args)

式でシーケンスを書く方法がわからない。writeの特性を悪用してorってみた。
どうかな。

In [275]: class some(object):
    @stm
    def foo():
        print "say foo"
    @staticmethod
    def bar():
        print "say bar"

In [301]: x = some()

In [302]: x.foo()
my static method
say foo

In [303]: x.bar()
say bar

いいっぽい。

classmethodをミミック

classmethodのほうはこうかな。

def clm(f):
    return lambda self, *args: sys.stdout.write("my static method\n") or f(type(self), *args)

第一引数変えただけ。

class another(object):
    @clm                                                                                    
    def foo(klass):
        print klass, " hello foo"
    @classmethod
    def bar(klass):
        print klass, " hello bar"

実験コード

In [12]: import sys

In [13]: x.foo()
my class method
<class '__main__.another'>  hello foo

In [14]: x.bar()
<class '__main__.another'>  hello bar

なるほどなるほど。

memoizeでfibってみる

というわけで気になったmemoizeを再発明してみる。

def memoize(f):
  memo = {}
  def inner(v):
      if v <0: return memo
      if not v in memo:
        memo[v] = f(v)
      return memo[v]
  return inner

@memoize
def fib(x):
    if x < 2: return x
    else: return fib(x-2) + fib(x-1)

こんな感じで。どだろう。

In [14]: fib(10)
Out[14]: 55

In [15]: fib(-1)
Out[15]: {0: 0, 1: 1, 2: 1, 3: 2, 4: 3, 5: 5, 6: 8, 7: 13, 8: 21, 9: 34, 10: 55}

おーるおっけいっぽい。
そ、そうだ、実は下のPSLの勉強用に作った回路の確認用に、ふとpythonでやってみたらこんな迷宮に入ってしまったのだった。なんかむなしいことをしてしまった気がする。まあリハビリにはちょうど良い*1

*1:rubyって大抵何かやろ、っと思うと既に用意されているんだけど, pythonってこういうことする率が高い気が。。。僕が知らないだけだろうな