Executar um certo código a cada n segundos [duplicado]
existe uma maneira de, por exemplo, imprimir Hello World!
a cada n segundos?
Por exemplo, o programa iria passar por qualquer código que eu tivesse, então uma vez que tivesse sido 5 segundos( com time.sleep()
) iria execute esse código. Eu estaria usando isso para atualizar um arquivo embora, não imprimir Olá Mundo.
por exemplo:
startrepeat("print('Hello World')", .01) # Repeats print('Hello World') ever .01 seconds
for i in range(5):
print(i)
>> Hello World!
>> 0
>> 1
>> 2
>> Hello World!
>> 3
>> Hello World!
>> 4
7 answers
import threading
def printit():
threading.Timer(5.0, printit).start()
print "Hello, World!"
printit()
# continue with the rest of your code
A minha humilde opinião sobre o assunto, uma generalização da resposta de Alex Martelli, com início() e fim () controlo:
from threading import Timer
class RepeatedTimer(object):
def __init__(self, interval, function, *args, **kwargs):
self._timer = None
self.interval = interval
self.function = function
self.args = args
self.kwargs = kwargs
self.is_running = False
self.start()
def _run(self):
self.is_running = False
self.start()
self.function(*self.args, **self.kwargs)
def start(self):
if not self.is_running:
self._timer = Timer(self.interval, self._run)
self._timer.start()
self.is_running = True
def stop(self):
self._timer.cancel()
self.is_running = False
Utilização:
from time import sleep
def hello(name):
print "Hello %s!" % name
print "starting..."
rt = RepeatedTimer(1, hello, "World") # it auto-starts, no need of rt.start()
try:
sleep(5) # your long-running job goes here...
finally:
rt.stop() # better in a try/finally block to make sure the program ends!
Características:
- apenas Biblioteca Padrão, sem dependências externas
-
start()
estop()
são seguros de ligar várias vezes, mesmo que o temporizador já tenha começado/parado - a função a ser chamada pode ter argumentos posicionais e nomeados
- Você pode mudar
interval
a qualquer momento, ele será eficaz após o próximo executar. O mesmo paraargs
,kwargs
e até mesmo!
O código é tão simples:
from apscheduler.scheduler import Scheduler
sched = Scheduler()
sched.start()
def some_job():
print "Every 10 seconds"
sched.add_interval_job(some_job, seconds = 10)
....
sched.shutdown()
def update():
import time
while True:
print 'Hello World!'
time.sleep(5)
Isso funcionará como uma função. O while True:
fá-lo correr para sempre. Podes sempre tirá-lo da função, se precisares.
Aqui está um exemplo simples compatível com APScheduler 3.00+:
# note that there are many other schedulers available
from apscheduler.schedulers.background import BackgroundScheduler
sched = BackgroundScheduler()
def some_job():
print('Every 10 seconds')
# seconds can be replaced with minutes, hours, or days
sched.add_job(some_job, 'interval', seconds=10)
sched.start()
...
sched.shutdown()
Em alternativa, pode utilizar o seguinte. Ao contrário de muitas alternativas, este temporizador irá executar o código desejado a cada n segundos exatamente (independentemente do tempo que leva para o código para executar). Portanto, esta é uma grande opção se você não pode dar-se ao luxo de qualquer deriva.
import time
from threading import Event, Thread
class RepeatedTimer:
"""Repeat `function` every `interval` seconds."""
def __init__(self, interval, function, *args, **kwargs):
self.interval = interval
self.function = function
self.args = args
self.kwargs = kwargs
self.start = time.time()
self.event = Event()
self.thread = Thread(target=self._target)
self.thread.start()
def _target(self):
while not self.event.wait(self._time):
self.function(*self.args, **self.kwargs)
@property
def _time(self):
return self.interval - ((time.time() - self.start) % self.interval)
def stop(self):
self.event.set()
self.thread.join()
# start timer
timer = RepeatedTimer(10, print, 'Hello world')
# stop timer
timer.stop()
n
segundos:
from threading import Event, Thread
def call_repeatedly(interval, func, *args):
stopped = Event()
def loop():
while not stopped.wait(interval): # the first call is in `interval` secs
func(*args)
Thread(target=loop).start()
return stopped.set
O evento é usado para parar as repetições:
cancel_future_calls = call_repeatedly(5, print, "Hello, World")
# do something else here...
cancel_future_calls() # stop future calls
Ver melhorar a implementação actual de uma python setInterval
Pode iniciar um tópico separado cujo único dever é contar durante 5 segundos, actualizar o ficheiro, repetir. Não vai querer que este fio separado interfira com o seu fio principal.