Welcome, guest | Sign In | My Account | Store | Cart

inspired by Steven Bethard's recipe at http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/442418 this class allows you to use an inner class as an extention of your class.

Python, 110 lines
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
class Property(object):
    _obj = []
    class __metaclass__(type):
        def __get__(cls, obj, objtype=None):
            if obj is not None:
                cls._obj.append( obj )
            return cls

    @staticmethod
    def parent_instancemethod(func):
        """
            decorator makes the decorated Property method behave like 
            the Property's parent's instance method
        """
        @classmethod
        def _parent_instancemethod(cls, *args, **kwds):
            return func(cls._obj.pop(), *args, **kwds)
        return _parent_instancemethod
    

    @staticmethod
    def parent_classmethod(func):
        """ 
            decorator makes the decorated Property method behave like 
            the Property's parent's class method
        """
        @classmethod
        def _parent_classmethod(cls, *args, **kwds):
            return func(cls._obj.pop().__class__, *args, **kwds)
        return _parent_classmethod

# Testing
if __name__ == "__main__":
    class A:
        a = 10
    
        def method1(self, *args, **kwds):
            print "-------------------------"
            print "In A.method1()"
            print "    Object: ", self
            print "    Arguements: ", args, kwds
            print "-------------------------"
    
        @classmethod
        def method2(cls, *args, **kwds):
            print "-------------------------"
            print "In A.method2()"
            print "    Class: ", cls
            print "    Arguements: ", args, kwds
            print "-------------------------"
    
        @staticmethod
        def method3(*args, **kwds):
            print "-------------------------"
            print "In A.method3()"
            print "    Arguements: ", args, kwds
            print "-------------------------"
    
        class B(Property):
            a = 99
            b = 'spam'
    
            @Property.parent_instancemethod
            def method1(self, *args, **kwds): 
                print "-------------------------"
                print "In A.B.method1()", args, kwds
                print "    Object: ", self
                print "    Arguements: ", args, kwds
                print "-------------------------"
    
            @Property.parent_classmethod
            def method2(cls, *args, **kwds): 
                print "-------------------------"
                print "In A.B.method2()"
                print "    Class: ", cls
                print "    Arguements: ", args, kwds
                print "-------------------------"
    
            @classmethod
            def method3(cls, *args, **kwds): 
                print "-------------------------"
                print "In A.B.method3()"
                print "    Class: ", cls
                print "    Arguements: ", args, kwds
                print "-------------------------"
    
            @staticmethod
            def method4(*args, **kwds): 
                print "-------------------------"
                print "In A.B.method4()"
                print "    Arguements: ", args, kwds
                print "-------------------------"

    x = A()
    print "x: ", x
    print "x.a: ", x.a
    print "x.B: ", x.B    

    x.method1(1, 2, 3)
    x.method2(4, 5, 6)
    x.method2(7, 8, 9)

    print
    print "x.B.a: ", x.B.a 
    print "x.B.b: ", x.B.b 

    x.B.method1('A', 'B', 'C')
    x.B.method2('D', 'E', 'F')
    x.B.method3('G', 'H', 'I')
    x.B.method4('J', 'K', 'L')

I found myself with a class and I wanted to be able to access a nested class like:

myclass.nestedclass.method(x)

Easy enough to do. But further, I wanted nestedclass.method to receive the myclass instance as it's first arguement, as any instance method of myclass would, so I could design nestedclass's methods as though they belonged to myclass. Not having a lot of experience with this sort of thing, I surfed around for answers and found Steven Bethard's recipe for using inner classes as properties. Tooling around with it, I came up with this. I'd appriciate comments, good or bad. Is there a better, easier way acheive the same thing? Is my implimentation of the idea fatally flawed?

1 comment

Paul Winkler 14 years, 5 months ago  # | flag

Why? It's a neat trick but you haven't said anything about what the motivation is. If the nested class' methods receive the outer class instance as first argument, what purpose does the nested class serve? Why not just define its methods directly on the outer class?

Created by Charles Josephs on Thu, 17 Nov 2005 (PSF)
Python recipes (4591)
Charles Josephs's recipes (1)

Required Modules

  • (none specified)

Other Information and Tasks