class Tracer(object):
def __init__(self, obj):
self._obj = obj
def __getattr__(self, attr):
if attr == '_obj':
return super().__getattr__(attr)
orig = getattr(self._obj, attr)
if callable(orig):
def wrapped(*args, **kwargs):
print("Calling {}.{} with {}, {}".format(
repr(self._obj), attr, repr(args), repr(kwargs)))
return orig(*args, **kwargs)
return wrapped
else:
print("Getting {}.{} = {}".format(repr(self._obj), attr, repr(orig)))
return orig
def __setattr__(self, attr, value):
if attr == '_obj':
super().__setattr__(attr, value)
return
print("Setting {}.{} to {}".format(repr(self._obj), attr, repr(value)))
setattr(self._obj, attr, value)