如何在Python中自动跳出死循环?

Sib*_*ing 4 python

我在Python中有一个"do ...,until ......"结构,如下所示:

while True:
    if foo() == bar():
        break
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,它工作正常(跳到最后).但是,在某些从未遇到过这种情况的情况下,它会卡在那里.

弄清楚这些情况是什么有点困难,因为它本质上是一个随机的过程.所以我希望为while循环设置一个"超时"的东西.

比如说,如果循环已运行1秒,但仍未停止,我希望循环终止.

我怎么能这样做?


更新:这是实际代码:

while True:
    possibleJunctions = junctionReachability[junctions.index(currentJunction)]
    nextJunction = random.choice(filter(lambda (jx, jy): (jx - currentJunction[0]) * (endJunction[0] - currentJunction[0]) > 0 or (jy - currentJunction[1]) * (endJunction[1] - currentJunction[1]) > 0, possibleJunctions) or possibleJunctions)
    if previousJunction != nextJunction: # never go back        
        junctionSequence.append(nextJunction)
        previousJunction = currentJunction
        currentJunction = nextJunction
    if currentJunction == endJunction:
        break
Run Code Online (Sandbox Code Playgroud)

Dan*_*Doe 7

import time

loop_start = time.time()
while time.time() - loop_start <= 1:
    if foo() == bar():
        break
Run Code Online (Sandbox Code Playgroud)


mpe*_*kov 5

编辑

Dan Doe的解决方案是最简单和最好的,如果您的代码是同步的(只在单个线程中运行),并且您知道foo并且bar函数总是在一段时间内终止.

如果您有异步代码(如GUI),或者您用于测试终止条件的foobar函数本身可能需要很长时间才能完成,请继续阅读.

在单独的线程/进程内运行循环.在另一个进程中运行计时器.一旦计时器到期,设置一个标志,导致循环终止.

像这样的东西(警告:未经测试的代码):

import multiprocessing
import time

SECONDS = 10
event = multiprocessing.Event()

def worker():
  """Does stuff until work is complete, or until signaled to terminate by timer."""
  while not event.is_set():
    if foo() == bar():
      break

def timer():
  """Signals the worker to terminate immediately."""
  time.sleep(SECONDS)
  event.set()

def main():
  """Kicks off subprocesses and waits for both of them to terminate."""
  worker_process = multiprocessing.Process(target=worker)
  timer_process = multiprocessing.Process(target=timer)
  timer_process.start()
  worker_process.start()
  timer_process.join()
  worker_process.join()

if __name__ == "__main__":
  main()
Run Code Online (Sandbox Code Playgroud)

如果你担心foobar功能花费太长时间才能完成,你可以明确地终止在工作进程的计时处理.

  • 嘿,什么是downvote?这是处理问题的有效方法; 以及它如何在异步场景(例如GUI)中完成. (2认同)