#!/usr/local/bin/python2 class ExtendableFunction(object): def __init__(self, func): self._base = func self._head = [] self._tail = [] def __call__(self, *args, **kwargs): for func in self._head: func(*args, **kwargs) result = self._base(*args, **kwargs) for func in self._tail: func(*args, **kwargs) return result @property def head(self): return self._head @property def tail(self): return self._tail @property def replica(self): base = self._base head = self._head[:] tail = self._tail[:] def f(*args, **kwargs): for func in head: func(*args, **kwargs) result = self._base(*args, **kwargs) for func in tail: func(*args, **kwargs) return result return f def p(*args): print 123 def q(*args): print 456 e = ExtendableFunction(bool) e.head.append(p) r = e.replica print r(1) e._base = str e.head.append(q) print e(1) print r(1)