如何从循环外部最好地停止循环?

3

我有一个打印旋转指针的 Python 脚本。希望这个指针可以一直持续到停止。

spinnerFrames = [
    "/",
    "-",
    "\\",
    "|",
]

def spinner():
  i = 0
  while True:
    clearScreen() #function to clear the screen
    print(spinnerFrames[i])
    i = i + 1
    if (i == 3):
      i = 0
    sleep(0.15)

spinner()
sleep(3)
# break out here
print("Done!")

我知道你可以使用sys.stdout.write()来删除那行代码,但那不是重点。

我无法找到最好的方法来停止循环并退出函数。(继续我的代码) 我希望能够在调用它的地方中断循环,因为我希望将其作为Pip软件包发布。

我认为这是可能的,但我不知道如何实现。感谢您的帮助!


1
你不能这样做。当你执行sleep(0.15)时,解释器会在spinner()函数中休眠。你应该在循环内部检查条件是否满足(例如,你正在等待的任何操作是否完成),如果满足则跳出循环。 - Pranav Hosangadi
除非循环结束并且函数返回,否则您的代码永远不会达到“在这里退出”部分。如果您想在其余代码执行时将旋转器作为另一个进程运行,则需要查看多处理。 - Chris Doyle
3个回答

6

您需要异步运行它,就像multiprocessing库允许您执行的那样。当您创建单独的线程时,将留下一个句柄,可以使用该句柄在希望停止时将其终止。

from multiprocessing import Process
from time import sleep
spinnerFrames = [
    "/",
    "-",
    "\\",
    "|",
]
def spinner():
  i = 0
  while True:
    print(spinnerFrames[i], end='\r')
    i = i + 1
    if (i == 3):
      i = 0
    sleep(0.15)
    
if __name__ == '__main__':
  p = Process(target=spinner)
  p.start()
  sleep(3)
  p.terminate()
  print("Done!")

这更像是一条评论而不是答案。我建议将其作为评论添加到问题中,或编写一个示例来解释答案。 - Chris Doyle
你如何异步运行它?我可以做到。 - Revel Carlberg West
谢谢您让我知道。我还是个新手,还在适应什么样的答案才是正确的。 - Lionel Foxcroft
2
@RevelCarlbergWest 这是使用Python进行异步编程的好起点- https://medium.com/velotio-perspectives/an-introduction-to-asynchronous-programming-in-python-af0189a88bbb - Brian16446
@LionelFoxcroft 谢谢,你的回答很棒。如果你愿意,可以放一个Python异步或一些代码的链接。不要感到奇怪,你帮了我! - Revel Carlberg West
显示剩余2条评论

2

这是我一个项目的参考实现。它打印点而不是旋转器,但更改它非常简单:

import threading
import time

def indicate_wait(func): 
    active = threading.Lock() 
     
    def dot_printer(): 
        while active.locked(): 
            print('.', end='', flush=True) 
            time.sleep(1) 
             
    def wrapper(*args, **kwargs): 
        t = threading.Thread(target=dot_printer) 
        active.acquire() 
        t.start() 
        res = func(*args, **kwargs) 
        active.release() 
        return res 
     
    return wrapper 

例子:

@indicate_wait 
def test(): 
    time.sleep(5) 

0

记录开始时间,如果当前时间 - 开始时间 > 持续时间,则跳出循环。

import time
spinnerFrames = [
    "/",
    "-",
    "\\",
    "|",
]

def spinner():
  i = 0
  startTime = time.time()# record starting time
  duration = 3
  while True:
    clearScreen() #function to clear the screen
    print(spinnerFrames[i])
    i = i + 1
    if (i == 3):
      i = 0
    if time.time() - startTime > duration:
      break
    sleep(0.15)

spinner()
print("Done!")

我可以这样做,但我只想在我想要的时候退出,而不是按持续时间。旋转器的目的是持续到某些加载完成,而不是一定的时间。 - Revel Carlberg West

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接