徹底比較!turtle.clear()とreset()、どちらで描画をリセットすべき?

2025-06-06

turtle.clear() は Python の turtle モジュールで使用される関数です。この関数は、タートルグラフィックスウィンドウ上で、タートルの描画をすべて消去します。 ただし、注意すべき重要な点がいくつかあります。

  1. 描画のみを消去: turtle.clear() は、タートルがこれまでに行った線や図形などの「描画」だけを消去します。
  2. タートルの状態はそのまま: タートル自身の位置、向き、色、ペンの状態(上がっているか下がっているかなど)は変更されません。タートルは、clear() が呼び出された時点のその場に留まり、その状態を維持します。

例:

import turtle

# スクリーンとタートルをセットアップ
screen = turtle.Screen()
t = turtle.Turtle()

# 四角形を描画
t.forward(100)
t.left(90)
t.forward(100)
t.left(90)
t.forward(100)
t.left(90)
t.forward(100)

# 少し待って描画を確認
screen.delay(1000) # 1秒待つ

# 描画をクリア
t.clear()

# タートルの位置や状態が変わっていないことを確認するために、何か別のものを描いてみる
t.circle(50) # タートルは以前の場所にいて、円を描く

上記のコードを実行すると、まず四角形が描画され、1秒後にその四角形が消えますが、タートル自体は画面上に残っており、その後、同じ場所から円を描き始めます。



    • 誤解: turtle.clear()は画面上のすべての描画を消去すると思っている。
    • 実際: turtle.clear()は、そのclear()メソッドが呼び出された特定のタートルオブジェクトによって描かれた線や図形のみを消去します。 複数のタートルがある場合、他のタートルが描いたものは消えません。また、画面(Screenオブジェクト)に直接描画されたものも消えません。
    • トラブルシューティング:
      • 画面全体をクリアしたい場合: turtle.Screen().clear() または turtle.clearscreen() を使用します。これらは画面上のすべてのタートルと描画を消去します。
      • 特定のタートルオブジェクトの描画だけを消したい場合: t.clear() のように、そのタートルオブジェクト(例: t)に対してclear()を呼び出しているか確認します。
      • スタンプを消去したい場合: clear()stamp() メソッドで押された「スタンプ」は消去しません。スタンプを消去するには turtle.clearstamp(stampid)turtle.clearstamps(n) を使用します。
  1. 「タートルが初期位置に戻らない」

    • 誤解: turtle.clear()を呼び出すと、タートルも初期位置(原点)に戻ると思っている。
    • 実際: turtle.clear()は描画のみを消去し、タートルの位置、向き、色、ペンの状態(penup()/pendown())などの状態は変更しません。 タートルはclear()が呼び出された時点のその場に留まります。
    • トラブルシューティング:
      • 描画を消去し、かつタートルを初期状態に戻したい場合: turtle.reset() を使用します。これは clear() の機能に加えて、タートルを原点 (0,0) に移動させ、右向きにし、ペンの状態なども初期値に戻します。
      • 特定の描画をクリアした後もタートルを現在の位置に維持したい場合は、clear() は正しい選択です。
  2. 「何も起こらない(描画が消えない)」

    • 誤解: clear() を呼び出したのに、描画が消えない。
    • 考えられる原因とトラブルシューティング:
      • 間違ったタートルオブジェクトにclear()を呼び出している: プログラムに複数のタートルオブジェクトがある場合、意図したタートルとは別のタートルに対してclear()を呼び出している可能性があります。例えば、t1 = turtle.Turtle()t2 = turtle.Turtle() があり、t1が描いたものを消したいのに t2.clear() を呼び出しているなど。
      • 画面の更新がされていない: turtle.tracer(0) などでアニメーションをオフにしている場合、clear()を呼び出しても画面がすぐに更新されないことがあります。この場合、turtle.update() を呼び出すことで画面を強制的に更新できます。
      • 非同期処理の問題: 特に複雑なプログラムで、clear()が期待されるタイミングで実行されていない可能性があります。コードの実行フローを確認してください。
      • スタンプを消そうとしている: 前述の通り、clear()はスタンプを消しません。clearstamp()clearstamps()を使用する必要があります。
      • グローバルなclear()とオブジェクトメソッドのclear()の混同: turtle.clear() (モジュールレベルの関数) と my_turtle.clear() (タートルオブジェクトのメソッド) は同じ振る舞いをします。通常は特定のタートルオブジェクトのメソッドとして呼び出すことが多いです。
  • エラーメッセージを読む: Pythonがエラーメッセージ(Traceback)を表示した場合、それを注意深く読むことで、何が問題なのかのヒントが得られます。AttributeError: 'Turtle' object has no attribute 'cleer' のようなメッセージはスペルミスを示唆しています。
  • 最小限の再現コードを作成する: 問題が発生した場合、問題の箇所だけを切り出した最小限のコードを作成してみると、原因を特定しやすくなります。
  • スペルミス: clearのスペルが正しいか、()が抜けていないかなどを確認してください。
  • import turtle を確認する: turtleモジュールが正しくインポートされているか確認してください。


例1: 基本的な turtle.clear() の使用

この例では、turtle.clear()特定のタートルの描画のみを消去し、タートルの位置や状態は変更しないことを示します。

import turtle
import time # 時間を待つために使用

# 1. スクリーンとタートルをセットアップ
screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.bgcolor("lightblue")
t = turtle.Turtle()
t.shape("turtle")
t.color("blue")
t.speed(1) # タートルの速度を遅くして視認しやすくする

# 2. 最初のアクション: 四角形を描く
print("四角形を描画中...")
for _ in range(4):
    t.forward(100)
    t.left(90)

time.sleep(2) # 2秒待って描画を確認

# 3. clear() を呼び出す
print("turtle.clear() を呼び出し中...")
t.clear() # タートルが描いた四角形を消去

time.sleep(1) # 1秒待って消去を確認

# 4. clear() 後もタートルの状態が変わっていないことを確認
# タートルは四角形を描き終えた位置(原点)に留まり、向きもそのまま
print("clear()後、別の図形(円)を描画中...")
t.circle(50) # 同じ場所から円を描く

screen.exitonclick() # クリックでウィンドウを閉じる

このコードのポイント

  • タートル自身は画面上に残り、四角形を描き終えた元の位置と向きを保ったままです。そのため、t.circle(50) を実行すると、以前の場所から円が描画されます。
  • t.clear() が呼び出されると、描かれた四角形だけが消えます。
  • 四角形が描画されます。

例2: 複数のタートルと clear()

この例では、複数のタートルが存在する場合に turtle.clear() がどのように動作するかを示します。

import turtle
import time

screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.bgcolor("lightgreen")

# 最初のタートル (青いタートル)
blue_turtle = turtle.Turtle()
blue_turtle.shape("turtle")
blue_turtle.color("blue")
blue_turtle.penup()
blue_turtle.goto(-100, 0)
blue_turtle.pendown()
blue_turtle.speed(1)

# 2番目のタートル (赤いタートル)
red_turtle = turtle.Turtle()
red_turtle.shape("turtle")
red_turtle.color("red")
red_turtle.penup()
red_turtle.goto(100, 0)
red_turtle.pendown()
red_turtle.speed(1)

# 青いタートルが四角形を描く
print("青いタートルが四角形を描画中...")
for _ in range(4):
    blue_turtle.forward(50)
    blue_turtle.left(90)

# 赤いタートルが三角形を描く
print("赤いタートルが三角形を描画中...")
for _ in range(3):
    red_turtle.forward(50)
    red_turtle.setheading(red_turtle.heading() - 120) # 120度回転

time.sleep(2)

# 青いタートルの描画のみをクリア
print("blue_turtle.clear() を呼び出し中...")
blue_turtle.clear()

time.sleep(2)

# 赤いタートルの描画をクリア
print("red_turtle.clear() を呼び出し中...")
red_turtle.clear()

screen.exitonclick()

このコードのポイント

  • これにより、clear() が特定のタートルオブジェクトに紐づいていることが明確に分かります。
  • その後、red_turtle.clear() を呼び出すと、赤いタートルが描いた三角形が消えます。
  • blue_turtle.clear() を呼び出すと、青いタートルが描いた四角形だけが消えます。 赤いタートルの三角形はそのまま残ります。
  • 青いタートルと赤いタートルがそれぞれ独立した図形を描きます。

この例では、clear()reset() の違いを示します。reset() は描画を消去するだけでなく、タートルの位置と向きも初期化します。

import turtle
import time

screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.bgcolor("lightyellow")

t = turtle.Turtle()
t.shape("arrow")
t.color("purple")
t.speed(1)

# 1. 描画と位置の移動
print("描画と位置の移動中...")
t.forward(100)
t.right(45)
t.forward(50)
t.color("red") # 色を変更
t.pensize(3)  # ペンの太さを変更

time.sleep(2)

# 2. clear() を使用
print("turtle.clear() を呼び出し中...")
t.clear() # 描画のみ消去、位置・向き・色・ペンサイズはそのまま

print("clear()後の状態確認: 線を引く...")
t.forward(50) # 赤いペンで太い線が描かれる(位置は前回の続き)

time.sleep(2)

# 3. reset() を使用
print("turtle.reset() を呼び出し中...")
t.reset() # 描画を消去し、タートルの位置、向き、色、ペンサイズも初期化

print("reset()後の状態確認: 線を引く...")
t.forward(50) # 黒い細い線が描かれる(原点から開始)

screen.exitonclick()
  • t.reset() を呼び出すと、描かれた線がすべて消えるだけでなく、タートルが原点 (0,0) に戻り、右向きになり、色もペンサイズも初期状態(黒、細い)に戻ります。 そのため、次に線を引くと黒くて細い線が原点から描かれます。
  • t.clear() を呼び出すと、描かれた線だけが消えます。 タートルは以前の位置に留まり、color("red")pensize(3) の状態を維持しています。そのため、次に線を引くと赤くて太い線になります。
  • 最初に紫色の細い線が描かれ、タートルが移動し、色とペンサイズが変更されます。


turtle.reset()

  • 使用例:
    import turtle
    import time
    
    t = turtle.Turtle()
    t.forward(100)
    t.left(90)
    t.forward(50)
    t.color("red") # 色を変更
    t.pensize(5)   # 太さを変更
    
    time.sleep(1)
    
    print("reset() を呼び出し中...")
    t.reset() # 描画をクリアし、タートルを初期状態に戻す
    
    t.forward(50) # 原点から黒い細い線が描かれる
    turtle.done()
    
  • 説明: reset() は、タートルが描いたすべての線や図形を消去し、タートルをスクリーンの中央(原点:(0,0))に移動させ、右向きに(0度の方向)し、ペンの色を黒、ペンの太さをデフォルト(1)に戻します。これは clear() よりも広範なリセットです。
  • 目的: 描画をクリアするだけでなく、タートル自身の状態(位置、向き、色、ペンの太さ、ペンアップ/ダウンの状態など)を初期値に戻したい場合。

turtle.Screen().clear() または turtle.clearscreen()

  • 使用例:
    import turtle
    import time
    
    screen = turtle.Screen()
    t1 = turtle.Turtle()
    t2 = turtle.Turtle()
    
    t1.penup()
    t1.goto(-50, 0)
    t1.pendown()
    t1.circle(50) # t1が円を描く
    
    t2.penup()
    t2.goto(50, 0)
    t2.pendown()
    for _ in range(4):
        t2.forward(50)
        t2.right(90) # t2が四角形を描く
    
    time.sleep(2)
    
    print("screen.clear() を呼び出し中...")
    screen.clear() # 画面上の全ての描画とタートルをクリア
    
    # 注意: ここで t1.forward(10) などとするとエラーになる
    # なぜなら t1 オブジェクトはもう存在しないから
    # 新しいタートルを作成する必要がある
    new_t = turtle.Turtle()
    new_t.forward(100)
    
    turtle.done()
    
  • 注意点: これを実行すると、画面全体がリセットされるため、既存のすべてのタートルオブジェクトは無効になります。
  • 説明: Screenオブジェクトのclear()メソッド、またはモジュールレベルのclearscreen()関数は、画面上のすべてのタートルの描画をクリアし、さらにすべてのタートルオブジェクト自体も削除します(タートルを再利用するには、新しいタートルオブジェクトを作成する必要があります)。
  • 目的: 画面(スクリーン)上のすべてのタートルと、すべての描画を完全に消去したい場合。これにより、複数のタートルが存在する場合でも、画面全体がまっさらになります。

turtle.Screen().resetscreen()

  • 使用例:
    import turtle
    import time
    
    screen = turtle.Screen()
    screen.bgcolor("orange") # 背景色を設定
    t = turtle.Turtle()
    t.circle(80)
    
    time.sleep(2)
    
    print("screen.resetscreen() を呼び出し中...")
    screen.resetscreen() # 画面設定も全て初期化
    
    # 新しいタートルを作成しないと描画できない
    new_t = turtle.Turtle()
    new_t.forward(50)
    print(f"現在の背景色: {screen.bgcolor()}") # デフォルトの背景色になっているはず
    
    turtle.done()
    
  • 説明: resetscreen()clearscreen() の機能に加えて、Screenオブジェクトのすべての設定(背景色、背景画像、リスナーなど)を初期値に戻します。
  • 目的: turtle.clearscreen() と似ていますが、画面(スクリーン)の設定(背景色、背景画像など)も初期状態に戻したい場合。

turtle.undo()

  • 使用例:
    import turtle
    import time
    
    t = turtle.Turtle()
    t.forward(100)
    t.left(90)
    t.forward(50)
    t.dot(10) # 点を打つ
    
    time.sleep(1)
    
    print("undo() を呼び出し中...")
    t.undo() # 直前のドットを消す
    
    time.sleep(1)
    
    print("再度 undo() を呼び出し中...")
    t.undo() # その前の線(forward(50))を消す
    
    turtle.done()
    
  • 説明: undo() メソッドは、タートルグラフィックスの履歴をさかのぼって、直前の操作を取り消します。これは clear() のようにすべての描画を一掃するのではなく、ステップバイステップで元に戻す際に便利です。
  • 目的: 直前の描画操作を元に戻したい場合(いわゆる「アンドゥ」機能)。
  • 使用例:
    import turtle
    import time
    
    t = turtle.Turtle()
    t.shape("triangle")
    t.penup()
    t.goto(-100, 0)
    
    stamps = []
    for _ in range(5):
        stamp_id = t.stamp() # スタンプを押し、IDを取得
        stamps.append(stamp_id)
        t.forward(50)
    
    time.sleep(1)
    
    print("t.clearstamps(2) を呼び出し中 (最新の2つを消去)...")
    t.clearstamps(2) # 最新の2つのスタンプを消去
    
    time.sleep(1)
    
    print("t.clearstamps() を呼び出し中 (全て消去)...")
    t.clearstamps() # 残り全てのスタンプを消去
    
    turtle.done()
    
  • 説明: turtle.clear() はタートルの「描画」(forward()などで引いた線)は消去しますが、stamp() で押されたスタンプは消しません。スタンプを消すにはこれらのメソッドを使用します。clearstamp() は特定のIDのスタンプを消し、clearstamps() は最新の n 個のスタンプ、またはすべてのスタンプを消します。
  • 目的: turtle.stamp() メソッドで押された「スタンプ」を消去したい場合。
メソッド対象タートルの状態スクリーンの状態
turtle.clear()特定のタートルの描画のみ維持される変更なし
turtle.reset()特定のタートルの描画 + タートルの状態初期化される変更なし
turtle.Screen().clear()画面上のすべての描画 + すべてのタートルタートルは削除変更なし
turtle.clearscreen()上記と同じタートルは削除変更なし
turtle.Screen().resetscreen()画面上のすべて + 画面設定タートルは削除初期化される
turtle.undo()直前の操作(描画履歴)変更される変更される
turtle.clearstamp() / clearstamps()スタンプ維持される変更なし