Search code examples
pythonclassrecursion

Can a class contain an instance of itself as a data container?


Can a python class contain an instance of itself as a data container may look like this?

class A:
    def __init__(self, val):
        self.a = A(val)
        self.val = val

aa = A(2) 
#this will cause RuntimeError: maximum recursion depth exceeded

My purpose is using this class as a data container contain a copy inside if it when it be inited to reduce the deepcopy action. It may used as an "undo" chain give a chance to get the init val's value when it's necessary.

Is it possible for such an action?


Solution

  • This won't work, for the reason already given:

    1. Python sees A(2) and calls A.__init__.
    2. A.__init__ calls A(val).
    3. A(val) calls A.__init__.
    4. GOTO 2

    I assume you're doing this so that you have a log of what val has been; that is, if sometime later you decide that you want val to be 3 instead, you don't throw away the original value 2. How about:

    Code

    class A( object ):
        @property
        def val( self ):
            return self.history[ -1 ]
    
        @val.setter
        def val( self, value ):
            self.history.append( value )
    
        def __init__( self, val ):
            self.history = [ ]
            self.val = val
    

    Explanation

    • A( object ): classes should now inherit from object. Just because, basically.
    • @property: this tells python that every time we ask for A.val, it should call A.val() and return the result. This is a decorator; look up the property builtin function for more information.
    • @val.setter: this is similar to the above, but tells Python that every time we try to assign to A.val it should call the following function instead. Instead of setting A.val, it appends the value to the history list.