「初めてのPython」で紹介されてるデコレータで、適用されて関数が呼ばれた回数を出力する。
class Tracer(object): """関数の呼び出し回数を保存して出力するデコレータ""" def __init__(self, func): self.calls = 0 self.func = func def __call__(self, *args): self.calls += 1 print "call %s to %s" % (self.calls, self.func.__name__) self.func(*args)
@Tracer def spam(): """spam doc string""" pass spam() # => call 1 to spam spam() # => call 2 to spam
ただし__name__とか__doc__は保存されない
print spam.__doc__ # => 関数の呼び出し回数を保存して出力するデコレータ print spam.__name__ # => AttributeError: 'Tracer' object has no attribute '__name__'
関数デコレータの場合はfunctools.wrapがこの辺の問題を解決してくれる
以下は「エキスパートPythonプログラミング」に載ってるサンプル
from functools import wraps def mydecorator(func): @wraps(func) def _mydecorator(*args, **kwargs): """_mydecorator doc string""" print 'before call %s' % func.__name__ res = func(*args, **kwargs) print 'after call %s' % func.__name__ return res return _mydecorator
クラスを使ったデコレータの場合どうするかと思って調べてみたら、こんな方法が簡単そうだった。
class Tracer(object): """関数の呼び出し回数を保存して出力するデコレータ""" def __init__(self, func): self.calls = 0 self.func = func def __call__(self, *args): self.calls += 1 print "call %s to %s" % (self.calls, self.func.__name__) self.func(*args) __doc__ = property(lambda self: self.func.__doc__) __name__ = property(lambda self: self.func.__name__) print spam.__doc__ # => spam doc string print spam.__name__ # => spam

- 作者: Mark Lutz,夏目大
- 出版社/メーカー: オライリージャパン
- 発売日: 2009/02/26
- メディア: 大型本
- 購入: 12人 クリック: 423回
- この商品を含むブログ (133件) を見る

- 作者: Tarek Ziade,稲田直哉,渋川よしき,清水川貴之,森本哲也
- 出版社/メーカー: KADOKAWA/アスキー・メディアワークス
- 発売日: 2010/05/28
- メディア: 大型本
- 購入: 33人 クリック: 791回
- この商品を含むブログ (92件) を見る