多次运行turtle编写的太阳系动画首次正常后续报Terminator错误如何解决
错误原因
turtle.Terminator错误是turtle库的全局状态残留导致的:turtle底层基于Tkinter实现,会全局维护运行状态标记,关闭绘图窗口后该标记会被设为终止状态。如果Python解释器没有完全退出(比如在IDE中反复运行脚本),这个终止状态不会自动重置,下一次运行调用turtle绘图、定时器相关接口时就会抛出该异常。
修复方案
调整代码逻辑,提前清理残留状态,主动捕获终止异常并在退出时清理定时器资源即可解决,修复后代码如下:
from turtle import Turtle, Screen import turtle """ Simulate motion of Mercury, Venus, Earth, and Mars """ # 强制清空上一次运行残留的屏幕对象,解决IDE反复运行的状态残留问题 turtle.Turtle._screen = None planets = { 'mercury': {'diameter': 0.383, 'orbit': 58, 'speed': 7.5, 'color': 'gray'}, 'venus': {'diameter': 0.949, 'orbit': 108, 'speed': 3, 'color': 'yellow'}, 'earth': {'diameter': 1.0, 'orbit': 150, 'speed': 2, 'color': 'blue'}, 'mars': {'diameter': 0.532, 'orbit': 228, 'speed': 1, 'color': 'red'}, } # 存储定时器ID,退出时用于取消未执行的回调 timer_id = None def setup_planets(planets): for planet in planets: dictionary = planets[planet] turtle_obj = Turtle(shape='circle') turtle_obj.speed("fastest") turtle_obj.shapesize(dictionary['diameter']) turtle_obj.color(dictionary['color']) turtle_obj.pu() turtle_obj.sety(-dictionary['orbit']) turtle_obj.pd() dictionary['turtle'] = turtle_obj global timer_id timer_id = screen.ontimer(revolve, 50) def revolve(): global timer_id try: for planet in planets: dictionary = planets[planet] dictionary['turtle'].circle(dictionary['orbit'], dictionary['speed']) timer_id = screen.ontimer(revolve, 50) except turtle.Terminator: # 检测到终止状态直接停止回调,避免抛出异常 if timer_id is not None: screen.ontimer(None, timer_id) return def on_close(): # 窗口关闭前先清理定时器资源再销毁窗口 global timer_id if timer_id is not None: screen.ontimer(None, timer_id) screen.bye() screen = Screen() # 绑定窗口关闭事件的自定义处理逻辑 screen._root.protocol("WM_DELETE_WINDOW", on_close) setup_planets(planets) screen.exitonclick()
核心改动说明
- 运行前先清空上一次残留的全局屏幕对象,消除状态残留影响
- 新增定时器ID存储,窗口关闭时主动取消未执行的回调,避免窗口销毁后回调仍然被触发
- 在动画逻辑中增加
Terminator异常捕获,检测到终止状态时直接停止回调链路 - 自定义窗口关闭逻辑,退出前优先清理资源再销毁窗口
内容的提问来源于stack exchange,提问作者Lachlan Davis
相关产品推荐
相关产品推荐

