如何彻底摧毁一个物体?

时间:2014-02-07 18:14:18

标签: python python-3.x tkinter

请帮助摧毁整个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()

问题是在我选择菜单项“关闭”后,屏幕显示对象self.area的引用数。对象self.area的引用数仍然不是0,而且2.也就是说,对象在内存中而不是垃圾回收

2 个答案:

答案 0 :(得分:1)

根据定义,如果你可以sys.getrefcount(someReferenceToAnObject),那么你仍然有对某个对象的引用,所以引用计数不能为零。

话虽如此,垃圾收集永远不会立竿见影,因此该对象的实际收集可能会发生得更晚。你真的不应该担心它。只要你在那时重新创建一个tkinter.Text,旧的就可能完全消失了垃圾收集。

话虽如此,如果你想减少引用次数,你可能也想在销毁之后做del self.area

答案 1 :(得分:0)

首先,您不仅要致电self.area.destroy(),还要通过self.area del self.areaself.area = None分离。这将从TP实例中删除引用。但是,TP可能会很快被销毁,所以这不是问题。虽然这还不够,显然,root对象包含对Text对象的引用(可能不是直接引用)。

无论如何,没有什么可担心的。在CPython(这是最广泛使用的Python实现)中,垃圾收集以一种导致立即删除具有零引用计数器的对象的方式完成。但是,并不能保证这种行为发生在任何地方。即使没有对象的引用,对象可能会被删除很多很多。并且没有可行的方法来强制立即销毁。