How to fully delete a turtle
Asked Answered
B

6

11

I made a small tkinter game that uses turtle for graphics. It's a simulation of the Triangle Peg Game from Cracker Barrel that is able to tell the player the next best move to make at any point in the game, among other features. Pegs are just instances of a subclass of turtle.RawPen, and I keep plenty of plain instances of RawPen around to draw arrows representing moves.

I noticed that when I restart the game (which calls turtle.bye()) to kill the turtle window, that memory consumption actually increases, as turtles don't seem to be deleted. Even if I call window.clear() beforehand, which clears _turtles in window.__dict__, there are still references to the turtles. I ensured that all the references that I make to them are deleted during restart, so that's not the issue. Is there any way to truly delete a turtle so it can be garbage collected?

Browse answered 15/5, 2017 at 5:52 Comment(3)
I played with this and concluded you have to call both window.clear() then window.bye() to get individual turtle reference counts to drop to zero. The .clear() takes care of window._turtles and the .bye() takes care of extra references caused by turtle event methods like onclick(). Can't say where your additional references are coming from.Uroscopy
I used gc.get_referrers() during debugging on all turtles used (I store them in peg_dir, graveyard, and artist_dir) and the only references were the list containing them, window._turtles, and event methods. I've tried clearing all my lists, using window.clear(), and then window.bye(), and gc.collect() says that the objects in peg_dir are unreachable. No idea why. I'll look into it.Browse
You need to delete it ... turtlely :-)Cleveite
B
2

Deleting all my references to objects in the canvas (including, of course, the TurtleWindow) and then destroying the canvas with canvas.destroy() did the trick. Perhaps there are other solutions, but this was the best that I could think of. I appreciate everyone's help, as it will serve me well in the future, at least with objects not created using the turtle API.

Browse answered 16/5, 2017 at 22:52 Comment(5)
Could you explain what you did? I am having the same issue.Cattleya
I just remembered that someone commented on this. I've been very busy, so sorry for not responding earlier. I'm a bit confused about what you're asking, though. I already described the problem and how I eventually solved it in this answer, my original post, and in comments to other answers.Browse
No problem! (Warning that this may be a stupid question.) "Deleting all my references to objects in the canvas" How did you do so?Cattleya
When I said "my references to objects in the canvas", I meant MY references: assignments that I explicitly made. For example, each instance of my TurtleGraphics class has a member called peg_dir, a list containing pegs (instances of a subclass of RawPen I made) that are currently visible to the player. In this case, a good way to delete the references would be to invoke peg_dir.clear(). My problem was that even though I had deleted MY references, I couldn't find a way to get tkinter/turtle to delete all ITS references.Browse
That makes sense. Thanks!Cattleya
C
2

The usual thing to do to get rid of data in turtles is reset():

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

For list of turtles, here kim,donald, fanny and frank are all turtles:

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

There is also an convenient code for all turtles on a specific screen, this is a built in list called (screen.turtles). So if You have a screen called screen:

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

for turtle in screen.turtles():
    turtle.reset()
Casseycassi answered 5/3, 2018 at 21:51 Comment(3)
Your reset() loop across screen.turtles() is effectively what turtle.resetscreen() (aka turtle.Screen().reset()) does. The significant memory freed (i.e. the OP's question) by turtle.reset() is clearing the turtle's undo buffer, other memory elements are simply reset to their default values. To help encourage garbage collection of turtles, use turtle.clearscreen() (aka turtle.Screen().clear()) and set all your turtle containing variables to None.Uroscopy
Perhaps screen._turtles.remove(turtle)? I have no idea if it's advisable or not.Score
@Score it's an idea, but even with turtle.reset(), trying to prune elements from _turtles seems to leak memory. There's a test in this post but it's possible I messed something up. Needless to say, messing with internals is probably a hacky workaround even if it did work. The same answer suggests an object pool, which seems like a stronger (possibly best?) solution for most use cases.Whisler
B
0

I've been thinking about how to delete a Turtle and here's what I came up with.

In a python shell, I created a Screen called wn and a Turtle named tracy:

>>>from turtle import Screen, Turtle 
>>>wn = Screen() 
>>>tracy = Turtle()

I checked my Screen's turtle list and there was tracy:

>>>print(wn._turtles)
[<turtle.Turtle object at 0x0000017F2722BC50>]

I managed to delete tracy by popping her out of the list:

>>>wn._turtles.pop()
<turtle.Turtle object at 0x0000017F2722BC50>

Afterwards, when I printed the turtle list, tracy was gone! Turtle deleted.

>>>print(wn._turtles)
[]
Bharat answered 7/2, 2024 at 0:4 Comment(0)
F
-1

Did you try deleting the memory-consuming object and then collecting the garbage explicitly using Python's built-in garbage collector interface?

import gc
...
# Delete memory-consuming object
del window._turtles
# Collect the garbage
gc.collect()
Filterable answered 15/5, 2017 at 14:51 Comment(2)
I tried that during debugging and the objects were unreachable, but I'll try again and make absolutely sure all references are gone. I don't see why that would help, though. Shouldn't garbage collection automatically occur anyway if there are no references left, and isn't it impossible to garbage collect if there are references, even explicitly?Browse
I once had a project in which one function made local use of a large Numpy array. I expected this array to be automatically garbage collected upon leaving the function scope, but my CPU usage indicated that Python still kept some hidden references to it... Calling del array and then gc.collect() before leaving the function enabled me to really free up the memory.Filterable
D
-1

I face the same problem I have a list of turtle and I want to delete them each time I loop into the list with:

 turtle.undo()
Dhumma answered 11/2, 2023 at 6:18 Comment(0)
F
-1

Just delete the turtle object present in the list containing turtle objects using del function of the list.

Flanders answered 29/5, 2024 at 0:44 Comment(1)
The problem was that the turtle library itself still had references to the objects I was trying to delete. By "reference", I mean that Python doesn't create a duplicate object every time you initialize a variable, append one to a list, etc. Say you have an existing object b, and initialize the variable a via a = b. a is not a copy of b, but to use a rough metaphor, is another name for b. My problem with the turtles is that there were some other "names" for them lying around that I couldn't find and get rid of.Browse

© 2022 - 2025 — McMap. All rights reserved.