Python Turtle `Пока верно` в управляемой событиями среде - PullRequest
1 голос
/ 07 марта 2020

Я прочитал в нескольких постах здесь о переполнении стека, что «В среде, управляемой событиями, такой как черепаха, никогда не должно быть while True:, поскольку она потенциально блокирует события (например, клавиатура).»

Вот это Python Программа Turtle, которая, кажется, работает нормально, но использует конструкцию while True:.

Может кто-нибудь объяснить, почему этот подход неправильный, что создает проблемы и каков правильный путь для достижения того же результата? ?

import turtle
import time


def move_snake():
    """
    This function updates the position of the snake's head according to its direction.
    """
    if head.direction == "up":
        head.sety(head.ycor() + 20)

def go_up():
    """
    callback for up key.
    """
    if head.direction != "down":
        head.direction = "up"

# Set up screen
screen = turtle.Screen()
screen.tracer(0)  # Disable animation so we can update screen manually.

# Event handlers
screen.listen()
screen.onkey(go_up, "Up")

# Snake head
head = turtle.Turtle()
head.shape("square")
head.penup()
head.direction = "stopped"  # Cheeky use of instance property to avoid global variable.


while True:
    move_snake()
    screen.update()
    time.sleep(0.2)

turtle.done()

1 Ответ

1 голос
/ 08 марта 2020

Я могу привести грубый пример. Запустите ваш код выше как есть. Начните движение змеи. Нажмите на кнопку закрытия окна. Подсчитайте количество строк сообщений об ошибках, которые вы получаете в консоли. Это может легко превысить два десятка.

Теперь попробуйте этот же эксперимент со следующим кодом, который исключает while True::

from turtle import Screen, Turtle

class Head(Turtle):
    def __init__(self):
        super().__init__(shape="square")

        self.penup()

        self.direction = "stopped"

def move_snake():
    if head.direction == "up":
        head.sety(head.ycor() + 20)
        screen.update()

    screen.ontimer(move_snake, 200)

def go_up():
    if head.direction != "down":
        head.direction = "up"

# Snake head
head = Head()

# Set up screen
screen = Screen()
screen.tracer(0)  # Disable animation so we can update screen manually.

# Event handlers
screen.onkey(go_up, "Up")
screen.listen()

move_snake()

screen.mainloop()

Количество сообщений об ошибках должно упасть до нуля. Это потому, что событие закрытия окна происходит в том же событии l oop, что и движение черепахи.

Существуют другие эффекты, которые вы в конечном итоге будете преследовать позже. Это просто, легко видимый.

...