如何在不中断整个循环的情况下以特定间隔在 while 循环中执行某些操作?

How can I do something within a while loop at a particular interval without interrupting the entire loop?

我有以下代码几乎可以满足我的需要:

import threading
import sched, time


def printit():
  threading.Timer(10.0, printit).start()
  print("Hello, World!")
  
  
x=25
printit()

while x>1:
    time.sleep(1)
    print(x)
    x=x-1 

它的作用是打印“Hello, World!”每 5 秒同时数字从 25 倒数到 2。我遇到的问题是我想把这个“你好,世界!”在循环内,以便在倒计时停止时停止。当我将它添加到循环中时,它会显示“Hello, World!”每秒和每 5 秒,当循环结束时,它仍然继续。我想我没有使用正确的模块,但我不确定。

编辑: 这是我尝试将其应用到的代码:

import threading
import sched, time
import numpy as np
import cv2
import imutils


flag = False
def printit():
    while(flag):
        print("Hello, world!")
        time.sleep(30)
          
t = threading.Thread(target=printit)
t.start()

fullbody_cascade = cv2.CascadeClassifier('haarcascade_fullbody.xml') #creates variables for the different cascades
upperbody_cascade = cv2.CascadeClassifier('haarcascade_upperbody.xml')
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
cap0 = cv2.VideoCapture(0) #chooses camera to be utilized

while True:
    
    ret0, frame0 = cap0.read() #reads the frames of the chosen camera
    
    gray0 = cv2.cvtColor(frame0, cv2.COLOR_BGR2GRAY) #converts to grayscale
     
    fullbody0 = fullbody_cascade.detectMultiScale(gray0) #detects the grayscaled frame
    upperbody0 = upperbody_cascade.detectMultiScale(gray0)
    face0 = face_cascade.detectMultiScale(gray0)
     
    for (x,y,w,h) in fullbody0:
        cv2.rectangle(frame0, (x,y), (x+w, y+h), (0,0,255), 2) #creates red a box around entire body
        
    for (x,y,w,h) in upperbody0:
        cv2.rectangle(frame0, (x,y), (x+w, y+h), (255,0,0), 2) #creates a blue box around upper body
    
    for (x,y,w,h) in face0:
        cv2.rectangle(frame0, (x,y), (x+w, y+h), (0,255,0), 2) #creates a green box around face
        flag = True
        time.sleep(0.5)
        
            
    flag = False 
    
    cv2.imshow('cam0',frame0)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break

cv2.destroyAllWindows()
  

我试过这样实现它,但它没有按预期工作。如果快速满足其中一个 for 循环的条件,它将快速打印“Hello, World!”,我该如何更改它以使其始终只打印“Hello, World!”每 x 秒一次,无论 for 循环条件满足多少次。

编辑 2: 上面的代码现在可以工作了,因为我对它做了一些轻微的编辑,问题是 for 循环移动得太快以至于打印消息不会显示,通过在 flag = True 语句后添加 time.sleep(0.5) , 它能够打印消息。感谢 Orius 的帮助!

努力去做

t = threading.Timer(5.0, printit)
t.start()

而不是

threading.Timer(5.0, printit).start()

然后,当您希望它停止时(while 循环结束后),执行

t.cancel()

希望对您有所帮助!

编辑:

哦,您需要可以从 printit() 外部访问。例如,您可以在 printit() 之外声明它,或者让 printit() return 它。

编辑 2:

抱歉,还有一个问题是你将 printit() 传递给计时器,其中 printit() 本身就是创建计时器的那个,所以有一个循环。

操作方法如下:

import threading
import sched, time


def printit():
  print("Hello, World!")

t =  threading.Timer(5.0, printit)
t.start() 
  
x=25
printit()

while x>1:
    time.sleep(1)
    print(x)
    x=x-1

t.cancel()

编辑 3:

用线程代替定时器:

import threading
import sched, time

flag = True

def printit():
    while(flag):
        time.sleep(5)
        print("Hello, world!")  
  
t = threading.Thread(target=printit)
t.start()

x=25

while x>1:
    time.sleep(1)
    print(x)
    x=x-1 

flag = False

您只想在第三个 for 循环运行时打印这些消息,对吗?我无法 运行 代码,因为我无法访问某些资源,但希望这应该有效:

import threading
import sched, time
import numpy as np
import cv2
import imutils

flag = False

def printit():
    while (True):
        time.sleep(2)
        if (flag)
            print("Hello, world!")  

t = threading.Thread(target=printit)
t.start()

fullbody_cascade = cv2.CascadeClassifier('haarcascade_fullbody.xml') #creates variables for the different cascades
upperbody_cascade = cv2.CascadeClassifier('haarcascade_upperbody.xml')
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
cap0 = cv2.VideoCapture(0) #chooses camera to be utilized

while True:
    
    ret0, frame0 = cap0.read() #reads the frames of the chosen camera
    
    gray0 = cv2.cvtColor(frame0, cv2.COLOR_BGR2GRAY) #converts to grayscale
     
    fullbody0 = fullbody_cascade.detectMultiScale(gray0) #detects the grayscaled frame
    upperbody0 = upperbody_cascade.detectMultiScale(gray0)
    face0 = face_cascade.detectMultiScale(gray0)
     
    for (x,y,w,h) in fullbody0:
        cv2.rectangle(frame0, (x,y), (x+w, y+h), (0,0,255), 2) #creates red a box around entire body
        
    for (x,y,w,h) in upperbody0:
        cv2.rectangle(frame0, (x,y), (x+w, y+h), (255,0,0), 2) #creates a blue box around upper body
    
    flag = True
    for (x,y,w,h) in face0:
        cv2.rectangle(frame0, (x,y), (x+w, y+h), (0,255,0), 2) #creates a green box around face
    flag = False 
    
    cv2.imshow('cam0',frame0)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break

cv2.destroyAllWindows()