Simplemente solicitando la opinión sobre si lo siguiente es razonable o si hay un mejor enfoque. Básicamente, quiero un decorador que se aplique a una función o una clase que implemente __call__.decorador de pitones para la clase O función
Puede simplemente tener un decorador regular y decorar el __call__ de forma explícita, pero luego el decorador está metido dentro de la definición de clase y es menos obvio. Tal vez me falta una solución más directa.
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)
Gracias. (Y si alguien está interesado, DzinX observa que la solución para hacerlo funcionar con las clases de estilo nuevo es verificar con inspect.isclass). –