admin管理员组

文章数量:1279087

I have a list with several turtle instances. I want to create a copy of one object and let this one move forward.

This works fine. But when I disable screen udpates and do it manually in my code it gives me a different result and I don't see the turtle on its new position. But I do see that it has moved there.

Here is an example. This produces the expected output. But as soon as I disable tracer and do a manual update it behaves weirdly.

from turtle import Screen, Turtle
from copy import copy


screen = Screen()
screen.setup(width=250, height=250)
#screen.tracer(0)

turtles = [Turtle(), Turtle()]

for i in range(10):
    #screen.update()

    new_turtle = copy(turtles[0])

    new_turtle.forward(10)
    turtles.append(new_turtle)

screen.exitonclick()

I have a list with several turtle instances. I want to create a copy of one object and let this one move forward.

This works fine. But when I disable screen udpates and do it manually in my code it gives me a different result and I don't see the turtle on its new position. But I do see that it has moved there.

Here is an example. This produces the expected output. But as soon as I disable tracer and do a manual update it behaves weirdly.

from turtle import Screen, Turtle
from copy import copy


screen = Screen()
screen.setup(width=250, height=250)
#screen.tracer(0)

turtles = [Turtle(), Turtle()]

for i in range(10):
    #screen.update()

    new_turtle = copy(turtles[0])

    new_turtle.forward(10)
    turtles.append(new_turtle)

screen.exitonclick()
Share Improve this question edited Feb 24 at 20:27 mkrieger1 23.2k7 gold badges64 silver badges80 bronze badges asked Feb 24 at 20:21 Denny CraneDenny Crane 6591 gold badge7 silver badges19 bronze badges 7
  • Is it intentional that you create 10 copies, not one copy? – mkrieger1 Commented Feb 24 at 20:29
  • It doesn't matter if 1, 10 or 100 copies. The code is just an example there. But it is supposed to work that way to use this approach in a more complex way. I boiled it down to the problem. :) – Denny Crane Commented Feb 24 at 21:11
  • Try using the turtle's .clone() method, rather than the generic copy.copy() - it's more likely to know how to properly do the job. – jasonharper Commented Feb 24 at 21:15
  • on Linux it doesn't work at all. It needs [-1] instead of [0]. And with copy() it moves all turtles to the same position - it would need deepcopy but it raise error. Only clone() gives expected result - I see may turtles (before using screen.update()) – furas Commented Feb 24 at 22:53
  • screen.update() should happen at the end of the loop, not the start, otherwise the last turtle in the loop will not be updated. Taking a step back, what feature are you trying to implement at a high level? There may be a better way than this if you don't mind providing context. – ggorlen Commented Feb 24 at 23:00
 |  Show 2 more comments

1 Answer 1

Reset to default 1

First: I had to use [-1] instead of [0] to see turtles in one line.


On my Linux it never works correctly with copy(). With trace(0) and without trace(0) it shows two turtles on screen (or both in the same place so I see only one). And screen.turtles() also shows only two turtles.

for turtle in screen.turtles():
    print(f'turtle: {turtle} : {turtle.pos()}')
turtle: <turtle.Turtle object at 0x72963525dfd0> : (0.00,0.00)
turtle: <turtle.Turtle object at 0x729635013d90> : (0.00,0.00)

I had to assign new _TurtleImage to turtle and append it to screen to see it on screen.
I found this in source code of .clone()

for i in range(10):

    new_turtle = copy(turtles[-1])
    new_turtle.turtle = _TurtleImage(screen, turtles[-1].turtle.shapeIndex)
    screen._turtles.append(new_turtle)

    new_turtle.forward(10)
    
    turtles.append(new_turtle)

    screen.update()

But in source code of .clone() you can see it makes other things.
And code always works for me when I use .clone() instead of copy().
And code is cleaner and shorter with .clone().

for i in range(10):

    new_turtle = turtles[-1].clone()    # works

    new_turtle.forward(10)
    
    turtles.append(new_turtle)

    screen.update()

I don't know why original code works for you without trace(0)
but I think standard method (without trace(0)) may do something more than only run update()
but I didn't find it in source code.


My full code which I used for test - with few other ideas in comments

from turtle import Screen, Turtle, _TurtleImage
from copy import copy, deepcopy


screen = Screen()
#screen.setup(width=250, height=250)
screen.tracer(0)

turtles = [Turtle(), Turtle()]

for i in range(10):

    #new_turtle = copy(turtles[-1])       # all turtles use the same position
    #new_turtle.screen = turtles[-1].screen
    #new_turtle.turtle = _TurtleImage(screen, turtles[-1].turtle.shapeIndex)
    #screen._turtles.append(new_turtle)

    #new_turtle = deepcopy(turtles[-1])  # raise error
    new_turtle = turtles[-1].clone()    # works

    new_turtle.forward(10)
    #new_turtle._update_data()
    #new_turtle._drawturtle()
    
    turtles.append(new_turtle)

    screen.update()

for index, t in enumerate(turtles, 1):
    print(f'{index:2}: {t.getscreen()} : {t.pos()}')
    
for turtle in screen.turtles():
    print(f'turtle: {turtle} : {turtle.pos()}')
        
screen.exitonclick()

本文标签: pythonTurtlescreenupdate() not working with copy methodStack Overflow