I want to wrap every method of various objects except __init__
using a decorator.
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)()
However, the wrapping of a property instance results is equivalent to this:
@my_decorator
@property
def result(self):
return "Some derived property"
When the desired result is something equivalent to this:
@property
@my_decorator
def result(self):
return "Some derived property"
It seems the attributes of a property object are read-only preventing modifying the function after property has wrapped it. I'm not too comfortable with the level of hackery required already and I'd rather not delve into the property object anyway.
The only other solution I can see is to generate a metaclass on the fly which I was hoping to avoid. Am I missing something obvious?