[我在Stack Overflow上的几篇文章中都读到““像乌龟这样的事件驱动环境永远不应该有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()
我可以提供一个粗略的例子。按原样运行您的代码。开始蛇移动。单击窗口的关闭按钮。计算在控制台中收到的错误消息的行数。可能会轻易超过两打。
现在用以下代码消除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()
您的错误消息计数应降至零。这是因为窗口关闭事件与乌龟运动在同一事件循环中发生。
还有其他效果,您稍后会追逐。这只是一个简单的,容易看到的。