1import types
2
3class Tracing:
4    def __init__(self, name, bases, namespace):
5        """Create a new class."""
6        self.__name__ = name
7        self.__bases__ = bases
8        self.__namespace__ = namespace
9    def __call__(self):
10        """Create a new instance."""
11        return Instance(self)
12
13class Instance:
14    def __init__(self, klass):
15        self.__klass__ = klass
16    def __getattr__(self, name):
17        try:
18            value = self.__klass__.__namespace__[name]
19        except KeyError:
20            raise AttributeError, name
21        if type(value) is not types.FunctionType:
22            return value
23        return BoundMethod(value, self)
24
25class BoundMethod:
26    def __init__(self, function, instance):
27        self.function = function
28        self.instance = instance
29    def __call__(self, *args):
30        print "calling", self.function, "for", self.instance, "with", args
31        return apply(self.function, (self.instance,) + args)
32
33Trace = Tracing('Trace', (), {})
34
35class MyTracedClass(Trace):
36    def method1(self, a):
37        self.a = a
38    def method2(self):
39        return self.a
40
41aninstance = MyTracedClass()
42
43aninstance.method1(10)
44
45print aninstance.method2()
46