Petr Krampl 的答案在我看来是最好的,但是关于循环的性质以及如何优化系统的使用,还需要多说一些。遇到此线程的初学者可能会被问题和现有答案中的逻辑和算法错误进一步混淆。
首先,让我们看看你的代码在你最初编写的时候做了什么:
while True:
test = 0
if test == 5:
break
test = test - 1
如果您在循环上下文中说while True,通常您的意图是永远留在循环中。如果这不是您的意图,您应该考虑循环结构的其他选项。 Petr Krampl 向您展示了一种非常合理的方法来处理这个问题,这对于可能阅读您代码的其他人来说更加清楚。此外,如果您需要重新访问代码以添加或修复某些内容,几个月后您会更加清楚。编写良好的代码是您文档的一部分。通常有多种方法可以做事,但这并不能使所有方法在所有情况下都同样有效。 while true 就是一个很好的例子,尤其是在这种情况下。
接下来,我们将查看原始代码中的算法错误。您在循环中做的第一件事就是将 0 分配给 test。接下来要做的是检查test 的值是否为5,除非您有多个线程修改相同的内存位置,否则永远不会出现这种情况。线程不在本次讨论的范围内,但值得注意的是代码在技术上可以工作,但即使有多个线程也会丢失很多,例如信号量。无论如何,无论哨兵强制执行无限循环,您都将永远处于此循环中。
test = test - 1 语句不管它做什么都是无用的,因为变量在循环的下一次迭代开始时被重置。即使您将其更改为test = 5,循环仍然是无限的,因为每次都会重置该值。如果将初始化语句移到循环之外,那么它至少有机会退出。你的意图可能是这样的:
test = 0
while True:
test = test - 1
if test == 5:
break
循环中语句的顺序取决于程序的逻辑。不过,它可以按任意顺序工作,这是重点。
下一个问题是从 0 开始,不断减 1,然后与正数比较的潜在和可能的逻辑错误。是的,在某些情况下,只要您了解其中的含义,这实际上可能就是您打算做的事情,但这很可能不是您想要做的。当您到达整数范围的“底部”(如 C 和其他各种语言)时,较新版本的 python 不会环绕。它会让您继续减 1,直到您填满系统上的可用内存或至少分配给您的进程的内存。看看下面的脚本和结果:
test = 0
while True:
test -= 1
if test % 100 == 0:
print "Test = %d" % test
if test == 5:
print "Test = 5"
break
产生这个:
Test = -100
Test = -200
Test = -300
Test = -400
...
Test = -21559000
Test = -21559100
Test = -21559200
Test = -21559300
...
test 的值永远不会是 5,所以这个循环永远不会退出。
为了补充 Petr Krampl 的答案,除了在一段时间后退出循环之外,这里的版本可能更接近您的实际意图:
import time
test = 0
timeout = 300 # [seconds]
timeout_start = time.time()
while time.time() < timeout_start + timeout:
if test == 5:
break
test -= 1
根据test 的值,它仍然不会中断,但这是一个具有合理初始条件的完全有效的循环。进一步的边界检查可以帮助您避免无缘无故执行很长的循环,例如检查循环进入时test的值是否小于5,这将立即中断循环。
应该提到另一件事,没有其他答案已经解决。有时当你像这样循环时,你可能不想在整个分配的时间内消耗 CPU。例如,假设您正在检查每秒变化的事物的值。如果您不引入某种延迟,您将使用分配给您的进程的每个可用 CPU 周期。如果有必要,那很好,但是好的设计将允许许多程序在您的系统上并行运行,而不会增加可用资源的负担。一个简单的 sleep 语句将释放分配给您的进程的绝大多数 CPU 周期,以便其他程序可以工作。
以下示例不是很有用,但它确实演示了这个概念。假设您想每秒打印一些内容。一种方法是这样的:
import time
tCurrent = time.time()
while True:
if time.time() >= tCurrent + 1:
print "Time = %d" % time.time()
tCurrent = time.time()
输出是这样的:
Time = 1498226796
Time = 1498226797
Time = 1498226798
Time = 1498226799
进程的 CPU 使用率如下所示:
这对于基本上不做任何工作来说是一个巨大的 CPU 使用量。这段代码对系统的其他部分更好:
import time
tCurrent = time.time()
while True:
time.sleep(0.25) # sleep for 250 milliseconds
if time.time() >= tCurrent + 1:
print "Time = %d" % time.time()
tCurrent = time.time()
输出是一样的:
Time = 1498226796
Time = 1498226797
Time = 1498226798
Time = 1498226799
而且 CPU 使用率要低得多: