Python object instantiation from within another object - is it a memory leak?
Question: Consider the following small Python GUI program, where the user can click a
button over and over to cycle between window 1 and window 2:

    
    
    import tkinter
    
    class Window1:
        def __init__(self, parent):
            # Initialize a new GUI window
            self.parent = parent
            self.window = tkinter.Toplevel(self.parent)
            self.window.title('Window 1')
    
            # Make a button to launch Window 2
            launch_window_2_button = tkinter.Button(self.window, text='Launch Window 2')
            launch_window_2_button.config(command=self.launch_window_2)
            launch_window_2_button.pack()
    
        def launch_window_2(self):
            self.window.destroy()
            Window2(self.parent)
    
    
    class Window2:
        def __init__(self, parent):
            # Initialize a new GUI window
            self.parent = parent
            self.window = tkinter.Toplevel(self.parent)
            self.window.title('Window 2')
    
            # Make a button to launch Window 1
            launch_window_1_button = tkinter.Button(self.window, text='Launch Window 1')
            launch_window_1_button.config(command=self.launch_window_1)
            launch_window_1_button.pack()
    
        def launch_window_1(self):
            self.window.destroy()
            Window1(self.parent)
    
    
    if __name__ == "__main__":
        # Initialize and hide the root GUI
        # (each class will spawn a new window that is a child of the root GUI)
        root = tkinter.Tk()
        root.withdraw()
        Window1(root) # Start by spawning Window 1
        root.mainloop()
    

**Question 1:** Since each new class is being instantiated from within another
class, is this a memory leak?

**Question 2:** Is this the most correct and Pythonic way to code this
application?

**Question 3:** Assuming that the answer to question 1 is no, what if I
changed `Window1(self.parent)` to `self.something = Window1(self.parent)`. Now
that there is a reference, is it a memory leak now?


Answer: > Question 1: Since each new class is being instantiated from within another
> class, is this a memory leak?

No. And I think you are confusing between a few things memory leak and object
references not being used. @kindall explains it beautifully in his comment
under your question.

The best way to understand what is going is to know that the
`tkinter.TopLevel(..)` constructor is [side-effects
based.](http://programmers.stackexchange.com/questions/40297/what-is-a-side-
effect) It will hold the reference to your window within the root object, so
that it knows how to deal with various windows. _And so is the constructor of
your class._ Once it creates a `self.window` and somehow has `root` have
reference to it, its job is done. The reference of this object is held too,
although not explicitly (see answer to your Question 3 below).

* * *

> Question 2: Is this the most correct and Pythonic way to code this
> application?

The fact that references to the objects `Window1` and `Window2` objects are
not used bugs me too. Other than that, I'd probably store away the references
of the window elements(buttons, etc) also within the object -- They might not
be of any immediate use, but they might be later on.

* * *

> Question 3: Assuming that the answer to question 1 is no, what if I changed
> the following lines:
>
> Window1(self.parent)
>
> to:
>
> self.something = Window1(self.parent)
>
> Now that there is a reference, is it a memory leak now?

Think about the below line:

    
    
    launch_window_2_button.config(command=self.launch_window_2)
    

In order for that line to work, tkinter has to store the reference of
`self.launch_window2` (and thereby `self`) somewhere, so your `self.something`
is not doing anything significant at all.. :)

