次のことが妥当かどうか、より良いアプローチがあるかどうかについて意見を求めるだけです。基本的には、__call__を実装する関数またはクラスに適用されるデコレータが必要です。クラスOR関数用のPythonデコレータ
__call__を明示的に装飾するだけでよく、デコレータはクラス定義内に隠されていて、それほど明白ではありません。たぶん私はもっと簡単な解決策を見逃しているかもしれません。
import types
from functools import wraps
class dec:
""" Decorates either a class that implements __call__
or a function directly.
"""
def __init__(self, foo):
self._foo = foo
def __call__(self, target):
wraps_class = isinstance(target, types.ClassType)
if wraps_class:
fun = target.__call__
else:
fun = target
@wraps(fun)
def bar(*args, **kwds):
val = args[1] if wraps_class else args[0]
print self._foo, val
return fun(*args, **kwds)
if wraps_class:
target.__call__ = bar
return target
else:
return bar
@dec('A')
class a:
# you could decorate here, but it seems a bit hidden
def __call__(self, val):
print "passed to a:", val
@dec('B')
def b(val):
print "passed to b:", val
a()(11)
b(22)
ありがとうございました。 (誰か興味があれば、DzinXはinspect.isclassでチェックすることで新しいスタイルのクラスで動作するように修正しています)。 –