クラスデコレータを使ってクラスのすべてのメソッドにデコレータを付加してみる。

クラスデコレータでクラス中のメソッド全部に入力出力の値を伝える機能を持たせてみる

class Inspector(object):
    depth = 0

    @classmethod
    def bind(kls, fn):
        def _bind(*args, **kw):
            indent = "  " * kls.depth
            print "%s %sargs=%s, kw=%s" % (indent, fn,  args, kw)
            kls.depth += 1
            result = fn(*args, **kw)
            kls.depth -= 1
            print "%s %sresult=%s" % (indent, fn, result)
            return result
        return _bind

def inspect_bind(klass):
    for m in klass.__dict__:
        fn = getattr(klass, m)
        if callable(fn) and not m.startswith("_"):
            setattr(klass, m, Inspector.bind(fn))
    return klass

@inspect_bind
class A(object):
    def f(self, i, j=10):
        return self.g(i*i, j)

    def g(self, i, j):
        return self.h(i+i, j)
    
    def h(self, i, j=10):
        return 3 if j<= 3 else self.m(i%3, j)
    
    def m(self, i, j):
        return self.n(i<<2, j)

    def n(self, i, j):
        return self.g(i, j-3) * self.f(i, j-2)

@inspect_bind
class Fib(object):
    def fib(self, n):
        return self.fib(n-2)+self.fib(n-1) if n >= 2 else n

結果

何ともどうでも良い内容。

 <unbound method A.f>args=(<__main__.A object at 0x243ebd0>, 100), kw={}
   <unbound method A.g>args=(<__main__.A object at 0x243ebd0>, 10000, 10), kw={}
     <unbound method A.h>args=(<__main__.A object at 0x243ebd0>, 20000, 10), kw={}
       <unbound method A.m>args=(<__main__.A object at 0x243ebd0>, 2, 10), kw={}
         <unbound method A.n>args=(<__main__.A object at 0x243ebd0>, 8, 10), kw={}
           <unbound method A.g>args=(<__main__.A object at 0x243ebd0>, 8, 7), kw={}
             <unbound method A.h>args=(<__main__.A object at 0x243ebd0>, 16, 7), kw={}
               <unbound method A.m>args=(<__main__.A object at 0x243ebd0>, 1, 7), kw={}
                 <unbound method A.n>args=(<__main__.A object at 0x243ebd0>, 4, 7), kw={}
                   <unbound method A.g>args=(<__main__.A object at 0x243ebd0>, 4, 4), kw={}
                     <unbound method A.h>args=(<__main__.A object at 0x243ebd0>, 8, 4), kw={}
                       <unbound method A.m>args=(<__main__.A object at 0x243ebd0>, 2, 4), kw={}
                         <unbound method A.n>args=(<__main__.A object at 0x243ebd0>, 8, 4), kw={}
                           <unbound method A.g>args=(<__main__.A object at 0x243ebd0>, 8, 1), kw={}
                             <unbound method A.h>args=(<__main__.A object at 0x243ebd0>, 16, 1), kw={}
                             <unbound method A.h>result=3
                           <unbound method A.g>result=3
                           <unbound method A.f>args=(<__main__.A object at 0x243ebd0>, 8, 2), kw={}
                             <unbound method A.g>args=(<__main__.A object at 0x243ebd0>, 64, 2), kw={}
                               <unbound method A.h>args=(<__main__.A object at 0x243ebd0>, 128, 2), kw={}
                               <unbound method A.h>result=3
                             <unbound method A.g>result=3
                           <unbound method A.f>result=3
                         <unbound method A.n>result=9
                       <unbound method A.m>result=9
                     <unbound method A.h>result=9
                   <unbound method A.g>result=9
                   <unbound method A.f>args=(<__main__.A object at 0x243ebd0>, 4, 5), kw={}
                     <unbound method A.g>args=(<__main__.A object at 0x243ebd0>, 16, 5), kw={}
                       <unbound method A.h>args=(<__main__.A object at 0x243ebd0>, 32, 5), kw={}
                         <unbound method A.m>args=(<__main__.A object at 0x243ebd0>, 2, 5), kw={}
                           <unbound method A.n>args=(<__main__.A object at 0x243ebd0>, 8, 5), kw={}
                             <unbound method A.g>args=(<__main__.A object at 0x243ebd0>, 8, 2), kw={}
                               <unbound method A.h>args=(<__main__.A object at 0x243ebd0>, 16, 2), kw={}
                               <unbound method A.h>result=3
                             <unbound method A.g>result=3
                             <unbound method A.f>args=(<__main__.A object at 0x243ebd0>, 8, 3), kw={}
                               <unbound method A.g>args=(<__main__.A object at 0x243ebd0>, 64, 3), kw={}
                                 <unbound method A.h>args=(<__main__.A object at 0x243ebd0>, 128, 3), kw={}
                                 <unbound method A.h>result=3
                               <unbound method A.g>result=3
                             <unbound method A.f>result=3
                           <unbound method A.n>result=9
                         <unbound method A.m>result=9
                       <unbound method A.h>result=9
                     <unbound method A.g>result=9
                   <unbound method A.f>result=9
                 <unbound method A.n>result=81
               <unbound method A.m>result=81
             <unbound method A.h>result=81
           <unbound method A.g>result=81
           <unbound method A.f>args=(<__main__.A object at 0x243ebd0>, 8, 8), kw={}
             <unbound method A.g>args=(<__main__.A object at 0x243ebd0>, 64, 8), kw={}
               <unbound method A.h>args=(<__main__.A object at 0x243ebd0>, 128, 8), kw={}
                 <unbound method A.m>args=(<__main__.A object at 0x243ebd0>, 2, 8), kw={}
                   <unbound method A.n>args=(<__main__.A object at 0x243ebd0>, 8, 8), kw={}
                     <unbound method A.g>args=(<__main__.A object at 0x243ebd0>, 8, 5), kw={}
                       <unbound method A.h>args=(<__main__.A object at 0x243ebd0>, 16, 5), kw={}
                         <unbound method A.m>args=(<__main__.A object at 0x243ebd0>, 1, 5), kw={}
                           <unbound method A.n>args=(<__main__.A object at 0x243ebd0>, 4, 5), kw={}
                             <unbound method A.g>args=(<__main__.A object at 0x243ebd0>, 4, 2), kw={}
                               <unbound method A.h>args=(<__main__.A object at 0x243ebd0>, 8, 2), kw={}
                               <unbound method A.h>result=3
                             <unbound method A.g>result=3
                             <unbound method A.f>args=(<__main__.A object at 0x243ebd0>, 4, 3), kw={}
                               <unbound method A.g>args=(<__main__.A object at 0x243ebd0>, 16, 3), kw={}
                                 <unbound method A.h>args=(<__main__.A object at 0x243ebd0>, 32, 3), kw={}
                                 <unbound method A.h>result=3
                               <unbound method A.g>result=3
                             <unbound method A.f>result=3
                           <unbound method A.n>result=9
                         <unbound method A.m>result=9
                       <unbound method A.h>result=9
                     <unbound method A.g>result=9
                     <unbound method A.f>args=(<__main__.A object at 0x243ebd0>, 8, 6), kw={}
                       <unbound method A.g>args=(<__main__.A object at 0x243ebd0>, 64, 6), kw={}
                         <unbound method A.h>args=(<__main__.A object at 0x243ebd0>, 128, 6), kw={}
                           <unbound method A.m>args=(<__main__.A object at 0x243ebd0>, 2, 6), kw={}
                             <unbound method A.n>args=(<__main__.A object at 0x243ebd0>, 8, 6), kw={}
                               <unbound method A.g>args=(<__main__.A object at 0x243ebd0>, 8, 3), kw={}
                                 <unbound method A.h>args=(<__main__.A object at 0x243ebd0>, 16, 3), kw={}
                                 <unbound method A.h>result=3
                               <unbound method A.g>result=3
                               <unbound method A.f>args=(<__main__.A object at 0x243ebd0>, 8, 4), kw={}
                                 <unbound method A.g>args=(<__main__.A object at 0x243ebd0>, 64, 4), kw={}
                                   <unbound method A.h>args=(<__main__.A object at 0x243ebd0>, 128, 4), kw={}
                                     <unbound method A.m>args=(<__main__.A object at 0x243ebd0>, 2, 4), kw={}
                                       <unbound method A.n>args=(<__main__.A object at 0x243ebd0>, 8, 4), kw={}
                                         <unbound method A.g>args=(<__main__.A object at 0x243ebd0>, 8, 1), kw={}
                                           <unbound method A.h>args=(<__main__.A object at 0x243ebd0>, 16, 1), kw={}
                                           <unbound method A.h>result=3
                                         <unbound method A.g>result=3
                                         <unbound method A.f>args=(<__main__.A object at 0x243ebd0>, 8, 2), kw={}
                                           <unbound method A.g>args=(<__main__.A object at 0x243ebd0>, 64, 2), kw={}
                                             <unbound method A.h>args=(<__main__.A object at 0x243ebd0>, 128, 2), kw={}
                                             <unbound method A.h>result=3
                                           <unbound method A.g>result=3
                                         <unbound method A.f>result=3
                                       <unbound method A.n>result=9
                                     <unbound method A.m>result=9
                                   <unbound method A.h>result=9
                                 <unbound method A.g>result=9
                               <unbound method A.f>result=9
                             <unbound method A.n>result=27
                           <unbound method A.m>result=27
                         <unbound method A.h>result=27
                       <unbound method A.g>result=27
                     <unbound method A.f>result=27
                   <unbound method A.n>result=243
                 <unbound method A.m>result=243
               <unbound method A.h>result=243
             <unbound method A.g>result=243
           <unbound method A.f>result=243
         <unbound method A.n>result=19683
       <unbound method A.m>result=19683
     <unbound method A.h>result=19683
   <unbound method A.g>result=19683
 <unbound method A.f>result=19683


 <unbound method Fib.fib>args=(<__main__.Fib object at 0x243ebd0>, 3), kw={}
   <unbound method Fib.fib>args=(<__main__.Fib object at 0x243ebd0>, 1), kw={}
   <unbound method Fib.fib>result=1
   <unbound method Fib.fib>args=(<__main__.Fib object at 0x243ebd0>, 2), kw={}
     <unbound method Fib.fib>args=(<__main__.Fib object at 0x243ebd0>, 0), kw={}
     <unbound method Fib.fib>result=0
     <unbound method Fib.fib>args=(<__main__.Fib object at 0x243ebd0>, 1), kw={}
     <unbound method Fib.fib>result=1
   <unbound method Fib.fib>result=1
 <unbound method Fib.fib>result=2