Bucle de Python para ejecutar durante cierta cantidad de segundos

4 minutos de lectura

avatar de usuario de oam811
oam811

Tengo un bucle while y quiero que siga ejecutándose durante 15 minutos. actualmente es:

while True:
    #blah blah blah

(Esto se ejecuta y luego se reinicia. Necesito que continúe haciendo esto, excepto que después de 15 minutos sale del ciclo)

¡Gracias!

Prueba esto:

import time

t_end = time.time() + 60 * 15
while time.time() < t_end:
    # do whatever you do

Esto se ejecutará durante 15 min x 60 s = 900 segundos.

Función time.time devuelve la hora actual en segundos desde el 1 de enero de 1970. El valor está en punto flotante, por lo que incluso puede usarlo con una precisión de subsegundos. Al principio, el valor t_end se calcula como “ahora” + 15 minutos. El bucle se ejecutará hasta que el tiempo actual exceda este tiempo de finalización preestablecido.

  • Gracias, lo probé originalmente con solo 60 segundos y se detuvo, así que sé que 15 minutos también funcionarán.

    – oam811

    23/06/2014 a las 20:39

  • Otra pregunta: ¿funciona la siguiente sintaxis? si las llaves[pygame.K_LEFT]: answer = “left” f = open(“answer.rtf”, “a”) f.write(answer) f.close() No me deja abrir el archivo de texto después, me pregunto si Estoy haciendo algo mal o si mi computadora está fallando.

    – oam811

    23 de junio de 2014 a las 20:43


  • Encontrar pequeños errores de sintaxis en el código es muy difícil a partir de los comentarios SO, por lo que tal vez debería crear otra pregunta. Sin embargo, al menos la operación si es incorrecta, debe haber == en lugar de =, y los dos puntos deben estar después de “izquierda”. Si no puede hacer que funcione con un esfuerzo razonable, publique otra pregunta. (Solo asegúrese de no hacer nada malo con la sangría).

    – DrV

    23 de junio de 2014 a las 20:48

  • @oam811: uso time.monotonic() en Python 3, para evitar retrasos inesperados debido a los ajustes del reloj de la máquina (time.time() puede retroceder).

    – jfs

    31 de agosto de 2014 a las 13:22

  • ¿Hay alguna forma de que me notifique si tuvo que omitir un bucle debido a la limitación de tiempo?

    –Renel Chesak

    16 oct 2017 a las 17:16

Si te entiendo, puedes hacerlo con un datetime.timedelta

import datetime

endTime = datetime.datetime.now() + datetime.timedelta(minutes=15)
while True:
  if datetime.datetime.now() >= endTime:
    break
  # Blah
  # Blah

  • Gracias, funcionó, pero estoy usando la respuesta de DrV solo porque tiene más sentido para mí.

    – oam811

    23/06/2014 a las 20:39

  • @Elliott, ¿Hay alguna razón por la que no usó una comparación now()

    – BobTuckerman

    04/04/2016 a las 15:43

  • @Bob Para coincidir con la pregunta de OP.

    – Elliot Frisch

    04/04/2016 a las 15:52

  • while True: bucle infinito con break la cláusula es más pitónica que la respuesta aceptada

    – gregV

    22 de julio de 2022 a las 3:41

Simplemente puedes hacerlo

import time
delay=60*15    ###for 15 minutes delay 
close_time=time.time()+delay
while True:
      ##bla bla
      ###bla bla
     if time.time()>close_time
         break

  • O incluso más simplemente while close_time>time.time(): sin necesidad de if time.time()>close_time: break

    – FrozenFyr

    10 de febrero de 2018 a las 9:43


Para aquellos que usan asyncio, una manera fácil es usar asyncio.wait_for():

async def my_loop():
    res = False
    while not res:
        res = await do_something()

await asyncio.wait_for(my_loop(), 10)

Estaba buscando un ciclo de tiempo más fácil de leer cuando encontré esta pregunta aquí. Algo como:

for sec in max_seconds(10):
      do_something()

Así que creé este ayudante:

# allow easy time-boxing: 'for sec in max_seconds(42): do_something()'
def max_seconds(max_seconds, *, interval=1):
    interval = int(interval)
    start_time = time.time()
    end_time = start_time + max_seconds
    yield 0
    while time.time() < end_time:
        if interval > 0:
            next_time = start_time
            while next_time < time.time():
                next_time += interval
            time.sleep(int(round(next_time - time.time())))
        yield int(round(time.time() - start_time))
        if int(round(time.time() + interval)) > int(round(end_time)): 
            return

Solo funciona con segundos completos, lo cual estuvo bien para mi caso de uso.

Ejemplos:

for sec in max_seconds(10) # -> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
for sec in max_seconds(10, interval=3) # -> 0, 3, 6, 9
for sec in max_seconds(7): sleep(1.5) # -> 0, 2, 4, 6
for sec in max_seconds(8): sleep(1.5) # -> 0, 2, 4, 6, 8

Tenga en cuenta que el intervalo no es tan preciso, ya que solo espero segundos completos (dormir nunca fue bueno para mí con tiempos

Avatar de usuario de Jan Lněnička
Jan Lněnička

La mejor solución para un mejor rendimiento es usar la respuesta de @DrV y la sugerencia de @jfs de usar time.monotonic():

    import time
    from datetime import datetime, timedelta

    count = 0
    end_time = time.monotonic() + 10
    while time.monotonic() < end_time:
        count += 1
    print(f'10 second result: {count=:,}')
    # 10 second result: count=185,519,745

    count = 0
    end_time = time.time() + 10
    while time.time() < end_time:
        count += 1
    print(f'10 second result: {count=:,}')
    # 10 second result: count=158,219,172

    count = 0
    end_time = datetime.now() + timedelta(seconds=10)
    while datetime.now() < end_time:
        count += 1
    print(f'10 second result: {count=:,}')
    # 10 second result: count=39,168,578

avatar de usuario de anonmak9
anonmak9

prueba esto:

import time
import os

n = 0
for x in range(10): #enter your value here
    print(n)
    time.sleep(1) #to wait a second
    os.system('cls') #to clear previous number
                     #use ('clear') if you are using linux or mac!
    n = n + 1

¿Ha sido útil esta solución?