[Python] Recurring Timer

Estándar

Hoy os dejo un pequeño snippet de código en Python para disponer de un temporizador recurrente que ejecute una función cada cierta cantidad de tiempo. Python dispone de un temporizador en el módulo Threading, pero sólo se puede utilizar para ejecutar la función después de pasada el tiempo de espera configurado, sin volver a repetirse.

class RecurringTimer(threading._Timer):
    """ Own implementation of timer to make it recurring

    Timer (based on threading._Timer)
    that invokes a method at a certain interval of seconds

    """
    
    def __init__ (self, *args, **kwargs):
        threading._Timer.__init__ (self, *args, **kwargs) 
        self.setDaemon (True)
        self._running = 0
        self._destroy = 0
        self.start()

    def run (self):
        while True:
            self.finished.wait (self.interval)
            if self._destroy:
                return;
            if self._running:
                self.function (*self.args, **self.kwargs)

    def start_timer (self):
        self._running = 1

    def stop_timer (self):
        self._running = 0

    def is_running (self):
        return self._running

    def destroy_timer (self):
        self._destroy = 1;

Como podéis ver, nos aprovechamos de la propia clase _Timer del módulo Threading (ya que Timer una función de conveniencia para crear una instancia de la clase _Timer) y reimplementamos el método run para hacer esperar al hilo la cantidad de tiempo necesaria y ejecutar el método si el temporizador no ha sido cancelado.

Lo podemos ejecutar de la siguiente manera:

if __name__ == "__main__":
    def sayhi (name):
        print 'hi %s' % name

    t = RecurringTimer(1.0, sayhi, ['alex952'])
    t.start_timer()

Este ejecución imprimirá hi alex952 cada segundo, de manera indefinida. Si deseamos parar el timer para poder reanudarlo posteriormente, los métodos stop_timer y start_timer están disponibles, y si, por el contrario deseamos deshacernos por completo del hilo que ocupa el temporizador, lo podemos hacer llamando el método destroy_timer.

Espero que os resulte de ayuda 🙂

Anuncios