当 while 循环的条件变为 False 时,跳出嵌套在 while 循环中的 for 循环

Break out of a for loop nested in a while loop when while loop's condition becomes False

我有一个迭代8秒的while循环,里面是一个for循环,迭代4次,每次执行一些pyautogui press函数。但是,当我的循环中断时,内部的 for 循环会继续直到完成。代码:

import time
import pyautogui

timeout = time.time() + 8


while time.time() < timeout:
    for i in range(4):
        pyautogui.press("1")
        pyautogui.press("1")
        pyautogui.press("1")
        pyautogui.press("1")
        pyautogui.press("1")
        pyautogui.press("1")
        pyautogui.press("1")
        pyautogui.press("1")
        pyautogui.press("1")
        pyautogui.press("1")
        pyautogui.press("4")
        pyautogui.press("enter")
print(f"{time.time() - timeout } seconds more than while loop execute time")

打印语句输出:

2.4774444103240967 seconds more than while loop execute time

那么,如何让我的 for 循环以我的 while 循环结束? 我检查了堆栈溢出但一无所获。

(使用 pyautogui.press("") 因为我在使用它们时出错,它们执行得比打印语句慢(可以更好地看到时差))

嗯,你的描述不符合实际情况。 “for”循环肯定会以“while”循环结束,但是你不能在中间打断“for”循环。如果您想在 mid-keystroke 停止,则需要在每次击键时检查时间:

import time
import pyautogui

timeout = time.time() + 8
msg = "11111111114*" * 4

for c in msg:
    if time.time() >= timeout:
        break
    if c == '*':
        c = 'enter'
    pyautogui.press(c)
print(f"{time.time() - timeout } seconds more than while loop execute time")

或者:

import time
import pyautogui

timeout = time.time() + 8
msg = (list("11111111114")+['enter']) * 4

while time.time() < timeout:
    if msg:
        pyautogui.press(msg.pop(0))
    else:
        time.sleep(0.1)

print(f"{time.time() - timeout } seconds more than while loop execute time")

您可以在适当定义的生成器上用对 next 的调用替换 while 循环的主体。从某种意义上说,这是线程的原始实现;生成器的执行与超时条件的重复评估交织在一起。 (在实践中,这可能仅作为线程如何工作的示例有用。)

def my_generator():
    for i in range(4):
        yield pyautogui.press("1")
        yield pyautogui.press("1")
        yield pyautogui.press("1")
        yield pyautogui.press("1")
        yield pyautogui.press("1")
        yield pyautogui.press("1")
        yield pyautogui.press("1")
        yield pyautogui.press("1")
        yield pyautogui.press("1")
        yield pyautogui.press("1")
        yield pyautogui.press("4")
        yield pyautogui.press("enter") 
    
foo = my_generator()

while time.time() < timeout:
    next(foo)