【问题标题】:How to fully delete a turtle如何完全删除乌龟
【发布时间】:2017-10-13 19:36:38
【问题描述】:

我制作了一个小型tkinter 游戏,它使用turtle 制作图形。这是对 Cracker Barrel 的 Triangle Peg Game 的模拟,它能够告诉玩家在游戏中的任何时候采取的下一个最佳动作,以及其他功能。钉子只是 turtle.RawPen 的子类的实例,我保留了大量的 RawPen 的普通实例来绘制代表移动的箭头。

我注意到当我重新启动游戏(调用turtle.bye())来杀死海龟窗口时,内存消耗实际上增加了,因为海龟似乎没有被删除。即使我事先调用了window.clear(),在window.__dict__ 中清除了_turtles,仍然有对海龟的引用。我确保在重新启动期间删除了我对它们所做的所有引用,所以这不是问题。有什么方法可以真正删除海龟,以便它可以被垃圾收集?

【问题讨论】:

  • 我玩过这个并得出结论,您必须同时调用 window.clear() 然后 window.bye() 才能使单个海龟引用计数降至零。 .clear() 负责处理window._turtles.bye() 负责处理由像onclick() 这样的乌龟事件方法引起的额外引用。无法说出您的其他参考资料来自哪里。
  • 我在调试所有使用的海龟时使用了gc.get_referrers()(我将它们存储在peg_dirgraveyardartist_dir),唯一的参考是包含它们的列表,window._turtles , 和事件方法。我尝试使用window.clear() 清除所有列表,然后使用window.bye(),而gc.collect() 表示peg_dir 中的对象无法访问。不知道为什么。我会调查的。

标签: python turtle-graphics


【解决方案1】:

删除我对画布中对象的所有引用(当然包括TurtleWindow),然后用canvas.destroy() 销毁画布就可以了。也许还有其他解决方案,但这是我能想到的最好的解决方案。感谢大家的帮助,因为它会在未来很好地为我服务,至少对于不是使用turtle API 创建的对象。

【讨论】:

  • 你能解释一下你做了什么吗?我有同样的问题。
  • 我只记得有人评论过这个。我最近很忙,很抱歉没有早点回复。不过,我对您的要求感到有些困惑。我已经在这个答案、我的原始帖子以及其他答案的 cmets 中描述了这个问题以及我最终如何解决它。
  • 没问题! (警告这可能是一个愚蠢的问题。)“删除我对画布中对象的所有引用”你是怎么做到的?
  • 当我说“我对画布中对象的引用”时,我指的是我的引用:我明确做出的分配。例如,我的TurtleGraphics 类的每个实例都有一个名为peg_dir 的成员,这是一个包含当前对玩家可见的钉子(我创建的RawPen 子类的实例)的列表。在这种情况下,删除引用的好方法是调用peg_dir.clear()。我的问题是,即使我删除了我的引用,我也找不到让tkinter/turtle 删除所有 ITS 引用的方法。
  • 这是有道理的。谢谢!
【解决方案2】:

删除海龟中的数据的通常做法是reset()

carl=Turtle()
.... code
carl.reset()

对于海龟列表,这里的 kim、donald、fanny 和 frank 都是海龟:

group=[kim,donald,fanny,frank]
for turtle in group:
    turtle.reset()

还有一个方便的代码用于特定屏幕上的所有海龟,这是一个名为 (screen.turtles) 的内置列表。因此,如果您有一个名为 screen 的屏幕:

screen=Screen()
...
code
....

for turtle in screen.turtles():
    turtle.reset()

【讨论】:

  • 您的reset() 循环穿过screen.turtles() 实际上就是turtle.resetscreen()(又名turtle.Screen().reset())所做的。 turtle.reset() 释放的重要内存(即 OP 的问题)正在清除海龟的 undo 缓冲区,其他内存元素只需重置为其默认值。为了帮助鼓励海龟的垃圾收集,请使用turtle.clearscreen()(又名turtle.Screen().clear())并将所有包含变量的海龟设置为无。
  • 也许是screen._turtles.remove(turtle)?我不知道这是否可取。
【解决方案3】:

您是否尝试过删除消耗内存的对象,然后使用 Python 的内置 garbage collector 接口显式收集垃圾?

import gc
...
# Delete memory-consuming object
del window._turtles
# Collect the garbage
gc.collect()

【讨论】:

  • 我在调试过程中尝试过,对象无法访问,但我会再试一次,并确保所有引用都消失了。不过,我不明白为什么这会有所帮助。如果没有留下引用,垃圾收集不应该自动发生吗?如果有引用,即使是明确的,也不可能进行垃圾收集吗?
  • 我曾经有一个项目,其中一个函数在本地使用了一个大型 Numpy 数组。我希望这个数组在离开函数作用域时自动被垃圾收集,但是我的 CPU 使用率表明 Python 仍然保留了一些对它的隐藏引用......在离开函数之前调用 del array 然后 gc.collect() 使我能够真正释放记忆。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-09
  • 1970-01-01
  • 2013-05-29
  • 1970-01-01
  • 2014-10-16
相关资源
最近更新 更多