Sergey
Sergey

Reputation: 1001

how to destroy an object completely?

please help to destroy, in whole self.area

import tkinter
import tkinter.messagebox
import sys


class TP(tkinter.Frame):

    def __init__(self, parent):
        tkinter.Frame.__init__(self, parent)
        self.pack(side = 'top', fill = 'x', expand = 'yes')
        self.parent = parent
        self.make_menu_bar()

    def make_menu_bar(self):
        self.menubar = tkinter.Menu(self) 
        self.parent.config(menu = self.menubar)                           

        self.file = tkinter.Menu(self.menubar)
        self.file.add_command(label = 'New', command = lambda: self.toggle_area(True))
        self.file.add_command(label = 'Close...', command = lambda: self.toggle_area(False))
        self.menubar.add_cascade(label = 'File', menu = self.file)

    def toggle_area(self, action):
        if action:
            self.area = tkinter.Text(self)
            self.area.pack(expand = 'yes', fill = 'both')
            print(sys.getrefcount(self.area))
        else:
            print(sys.getrefcount(self.area))
            self.area.destroy()
            print(sys.getrefcount(self.area))


if __name__ == '__main__':
    root = tkinter.Tk()
    TP(root)
    root.mainloop()

the problem is that after I select the menu item "Close", the screen shows the number of references to the object self.area. number of references to the object self.area still not 0, and 2. that is, the object is in memory and is not garbage collected

Upvotes: 0

Views: 1387

Answers (2)

poke
poke

Reputation: 387587

By definition, if you can do sys.getrefcount(someReferenceToAnObject) then you still have some reference to an object, so the reference count cannot be zero.

That being said, garbage collection is never immediate, so the actual collection of that object may happen much later. You really shouldn’t worry about it though. As soon as you recreate a tkinter.Text at that point, the old is probably completely gone and up for garbage collection.

That being said, if you want to reduce the reference count, you probably want to do del self.area after destroying it too.

Upvotes: 1

Ellioh
Ellioh

Reputation: 5330

First of all, you have not just to call self.area.destroy(), but to detach from self.area by doing del self.area of self.area = None. That would remove a reference from the TP instance. However, TP is likely to be destroyed very soon, so this is not a problem. Though it's not enough, apparently, the root object holds a reference to your Text object (maybe not directly).

Anyway, there is nothing to worry about. In CPython (that is the most widely used implementation of Python) garbage collection is done in a way that causes immediate deletion of an object with zero reference counter. However, it is not guaranteed that such a behavior takes place everywhere. Probably the objects may be deleted much, much later even if there are no references to them. And there is no portable way to enforce immediate destruction.

Upvotes: 0

Related Questions