Просто запрашиваю мнение о том, является ли нижеследующее разумным или есть лучший подход. В основном мне нужен декоратор, который будет применяться к функции или классу, реализующему __call__.
Вы могли бы просто иметь обычный декоратор и явно украсить __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)