#!/usr/local/bin/python2 import functools import inspect class C(object): def __init__(self): print "init" def _a(self): print "_a" def b(self): print "b" class ExtendableFunction(object): def __init__(self, base): self._base = base self._pre_hooks = [] self._post_hooks = [] def __call__(self): self.snapshot() @property def pre_hooks(self): return self._pre_hooks @property def post_hooks(self): return self._post_hooks @property def snapshot(self): base = self._base pre_hooks = self._pre_hooks[:] post_hooks = self._post_hooks[:] def extended_func(*args, **kwargs): for hook in pre_hooks: hook(*args, **kwargs) result = base(*args, **kwargs) for hook in post_hooks: hook(*args, **kwargs) return result return extended_func @classmethod def override(cls, obj): for name, value in inspect.getmembers(obj, inspect.ismethod): if name[0] != '_': setattr(obj, name, functools.update_wrapper(cls(value), value)) c = C() c._a() c.b() ExtendableFunction.override(c) print c.__init__.pre_hooks