请帮助摧毁整个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.也就是说,对象在内存中而不是垃圾回收
答案 0 :(得分:1)
根据定义,如果你可以sys.getrefcount(someReferenceToAnObject)
,那么你仍然有对某个对象的引用,所以引用计数不能为零。
话虽如此,垃圾收集永远不会立竿见影,因此该对象的实际收集可能会发生得更晚。你真的不应该担心它。只要你在那时重新创建一个tkinter.Text
,旧的就可能完全消失了垃圾收集。
话虽如此,如果你想减少引用次数,你可能也想在销毁之后做del self.area
。
答案 1 :(得分:0)
首先,您不仅要致电self.area.destroy()
,还要通过self.area
del self.area
与self.area = None
分离。这将从TP
实例中删除引用。但是,TP
可能会很快被销毁,所以这不是问题。虽然这还不够,显然,root
对象包含对Text
对象的引用(可能不是直接引用)。
无论如何,没有什么可担心的。在CPython(这是最广泛使用的Python实现)中,垃圾收集以一种导致立即删除具有零引用计数器的对象的方式完成。但是,并不能保证这种行为发生在任何地方。即使没有对象的引用,对象可能会被删除很多很多。并且没有可行的方法来强制立即销毁。