如何修复Python Turtle蠕虫游戏中的RecursionError递归错误?
问题原因及修复方案
错误根源
你遇到的RecursionError是因为:
- 用
onkeypress绑定左右键后,按住按键会反复触发left()/right()函数; - 每个
left()/right()里又调用go(),而go()里的while循环会占用线程,导致新的按键触发请求只能堆叠在函数调用栈中; - 当调用栈的层数超过Python默认的递归深度限制(约1000层)时,程序就会崩溃抛出错误。
另外原代码里的全局变量t没有被正确使用,go()里重新定义了t=0,不过这不是核心问题。
修复后的代码
import turtle # 设置窗口和背景 wn = turtle.Screen() wn.title("用左右方向键转向,点击窗口退出") wn.bgcolor("black") # 蠕虫设置 snake = turtle.Turtle() snake.color("purple") snake.shape("circle") snake.shapesize(0.25, 0.25) snake.pensize(5) snake.speed(0) # 设为最快,移动节奏由ontimer控制 # 控制移动的状态标志 is_moving = True def move_forward(): if is_moving: snake.forward(1) # 每10毫秒调用一次,实现持续移动(可调整数值改速度) wn.ontimer(move_forward, 10) def left(): snake.circle(1, 8) # 每次左转8度 def right(): snake.circle(1, -8) # 每次右转8度 # 绑定按键:按住左右键持续转向 wn.onkeypress(left, "Left") wn.onkeypress(right, "Right") wn.listen() # 点击窗口退出时停止移动并关闭窗口 def exit_program(): global is_moving is_moving = False wn.bye() wn.onclick(exit_program) # 启动持续移动 move_forward() turtle.done()
关键修改说明
- 移除阻塞式循环:把原
go()里的while循环换成turtle的ontimer()方法,实现非阻塞的持续移动,让事件循环能正常处理按键输入,避免调用栈堆叠。 - 分离移动与转向逻辑:移动逻辑单独放在
move_forward()里,转向只是调整角度,不会阻塞移动,两者通过事件循环并行调度。 - 简化按键绑定:只保留
onkeypress处理按住按键的持续转向,无需重复绑定onkey。 - 添加退出控制:用
is_moving标志确保退出时停止移动,避免残留操作。
内容的提问来源于stack exchange,提问作者Mira
相关产品推荐
相关产品推荐

