デコレータの元関数を保存する
テスト等でデコレータのデコレート前の関数を保存する必要があるなら、こんなのはどうだろう?
import sys def tee(f): sys._getframe(1).f_locals['_raw_'+f.func_name] = f return f
デコレートした関数オブジェクトから元の関数を取り出すのは難しいし、テスト対象のモジュールをインポートするときに一時的にデコレータを置き換える手では安定した動作は難しい。また、外部のモジュールを再利用することを考えると、デコレータ関数に手を入れるのは避けたい。
というわけで思いついたのは上のデコレータだ。こんな感じで使う:
def deco(f): def wrapper(*args, **kwargs): print "wrapper", f return f(*args, **kwargs) return wrapper @deco @tee def spam(): print "spam" spam() _raw_spam() class Ham(object): @deco @tee def egg(self): print "egg" Ham().egg() Ham()._raw_egg()
一番最初に実行されるデコレータとして、tee
を指定しておくと、その関数オブジェクトを_raw_xxxx
という名前で同じスコープに登録するようになっている。テスト等でデコレータ無しで実行したい場合には、この_raw_xxxx
を使うことができる。
まあ、テスト用のコードをこういう形で本体のソースに追加するのもどうかと思うし、自分ではこのアイデアは使わない気がするが。