Decorar un método de clase después de @property
Quiero envolver cada método de varios objetos excepto__init__
usando un decorador.
class MyObject(object):
def method(self):
print "method called on %s" % str(self)
@property
def result(self):
return "Some derived property"
def my_decorator(func):
def _wrapped(*args, **kwargs):
print "Calling decorated function %s" % func
return func(*args, **kwargs)
return _wrapped
class WrappedObject(object):
def __init__(self, cls):
for attr, item in cls.__dict__.items():
if attr != '__init__' and (callable(item) or isinstance(item, property)):
setattr(cls, attr, my_decorator(item))
self._cls = cls
def __call__(self, *args, **kwargs):
return self._cls(*args, **kwargs)
inst = WrappedObject(MyObject)()
Sin embargo, el ajuste de los resultados de una instancia de propiedad es equivalente a esto:
@my_decorator
@property
def result(self):
return "Some derived property"
Cuando el resultado deseado es algo equivalente a esto:
@property
@my_decorator
def result(self):
return "Some derived property"
Parece que los atributos de un objeto de propiedad son de solo lectura, lo que impide modificar la función una vez que la propiedad lo ha envuelto. Ya no me siento muy cómodo con el nivel de piratería requerido y prefiero no profundizar en el objeto de propiedad de todos modos.
La única otra solución que puedo ver es generar una metaclase sobre la marcha que esperaba evitar. ¿Me estoy perdiendo algo obvio?