如何在 Trinket 环境中正确实现海龟点击变色功能

trinket 的 turtle 库中 `fillcolor()` 仅支持设值(setter),不支持取值(getter),因此不能通过 `self.fillcolor() == ...` 判断当前颜色;需手动维护颜色状态变量并同步调用 `fillcolor()` 更新显示。

在标准 Python(如本地 Windows + Python 3.10)中,turtle.Turtle.fillcolor() 是一个双向函数:既可设置填充色(如 t.fillcolor("red")),也可获取当前填充色(如 t.fillcolor() 返回 "red")。但 Trinket 的 Web 版 Turtle 实现是精简版,其 fillcolor()、pencolor() 等方法仅作为 setter 使用——调用时不带参数会触发 JavaScript 层的未定义行为(如 Cannot read properties of undefined),导致运行时报错。

要使代码在 Trinket 中稳定运行,关键原则是:不依赖 fillcolor() 的返回值做逻辑判断,而是显式维护颜色状态。以下是推荐的修复方案:

import turtle

class ToggleTurtle(turtle.Turtle):
    COLOR_1 = "red"
    COLOR_2 = "blue"

    def __init__(self):
        super().__init__()
        self.shape("turtle")
        self.current_color = self.COLOR_1  # 显式记录当前填充色
        self.fillcolor(self.current_color)  # 初始化显示
        self.onclick(self.toggle_color)

    def toggle_color(self, x, y):
        # 切换内部状态,再同步更新图形
        if self.current_color == self.COLOR_1:
            self.current_color = self.COLOR_2
        else:
            self.current_color = self.COLOR_1
        self.fillcolor(self.current_color)  # 强制重设,确保视觉一致

# 启动交互
tt = ToggleTurtle()
turtle.done()

优势说明

  • 完全规避对 fillcolor() 返回值的依赖,兼容 Trinket 与标准 Python 环境;
  • 使用类常量 COLOR_1/COLOR_2 提升可维护性;
  • current_color 作为单一事实源(single source of truth),避免状态与视图脱节。

⚠️ 注意事项

  • Trinket 的 Turtle 不支持 RGB 元组或三参数形式的 fillcolor(r, g, b)(如 fillcolor(255, 0, 0)),请统一使用命名颜色字符串(如 "red"、"cyan")或十六进制(如 "#FF0000");
  • 若需扩展多色切换,可将 current_color 改为索引(如 self.color_index = 0)配合颜色列表管理;
  • 所有图形更新操作(如 fillcolor、pencolor、shape)必须在 onclick 回调内显式调用,Trinket 不自动同步状态。

此方案兼顾健壮性与可移植性,是面向教育场景(如课堂编程平台)的最佳实践。