Outils pour utilisateurs

Outils du site


fonction_periodique

Comment appeler une fonction périodiquement (toutes les x secondes)

Objectif

On voudrait qu'une fonction puisse être appelée toutes les x secondes avec les caractéristiques suivantes:

  • lancement au moment choisi dans le déroulement du programme
  • la fonction doit pouvoir être appelée avec ses arguments définis à chaque lancement
  • le programme principal doit pouvoir poursuivre son déroulement normalement
  • on doit pouvoir arrêter à la demande dans le déroulement du programme

Codage proposé

On utilise ici un thread qui lance un Timer dans une boucle et qui attend que ce Timer se termine (.join()). Une fois la durée d'attente prévue, le Timer lance la fonction avec les arguments définis et se termine, ce qui permet la relance d'un nouveau Timer.

L'appel à la méthode stop() permet d'arrêter un éventuel Timer en cours d'attente et d'empêcher une nouvelle boucle: le thread s'arrête donc.

Tel que programmée, la classe peut être placée dans un module.

On peut sans difficulté modifier la durée de l'intervalle “à la volée”. Il suffit d'affecter une autre valeur à t.duree, qui sera prise en compte à la prochaine boucle.

import threading
 
class Intervallometre(threading.Thread):
 
    def __init__(self, duree, fonction, args=[], kwargs={}):
        threading.Thread.__init__(self)
        self.duree = duree
        self.fonction = fonction
        self.args = args
        self.kwargs = kwargs
        self.encore = True  # pour permettre l'arret a la demande
 
    def run(self):
        while self.encore:
            self.timer = threading.Timer(self.duree, self.fonction, self.args, self.kwargs)
            self.timer.setDaemon(True)
            self.timer.start()
            self.timer.join()
 
    def stop(self):
        self.encore = False  # pour empecher un nouveau lancement de Timer et terminer le thread
        if self.timer.isAlive():
            self.timer.cancel()  # pour terminer une eventuelle attente en cours de Timer

Utilisation


Voilà 3 exemples de fonctions à appeler avec plusieurs façons de coder les arguments:

def affiche(ch, x="machin", y="truc"):
    print "top" + ' ' + ch + ' ' + x + ' ' + y
 
def affiche2(*args, **kwargs):
    ch = "top"
    ch += ' ' + args[0]
    ch += ' ' + kwargs['x']
    ch += ' ' + kwargs['y']
    print ch
 
def affiche3(*args, **kwargs):
    ch = "top"
    for arg in args:
        ch += ' ' + arg
    d = kwargs.items()
    d.sort()
    for cle, valeur in d:
        ch += ' ' + valeur
    print ch


Et voilà comment on appelle l'intervallometre:

import time
 
duree = 0.5
 
t =  Intervallometre(duree, affiche, ["toto"], {'x':"titi", 'y':"tata"})
t.setDaemon(True)
t.start()
 
time.sleep(5.1)
t.stop()
 
t2 =  Intervallometre(duree, affiche2, ["toto2"], {'x':"titi", 'y':"tata"})
t2.setDaemon(True)
t2.start()
 
time.sleep(5.1)
t2.stop()
 
t3 =  Intervallometre(duree, affiche3, ["toto3"], {'x':"titi", 'y':"tata"})
t3.setDaemon(True)
t3.start()
 
time.sleep(5.1)
t3.stop()


ce qui affichera:

top toto titi tata
top toto titi tata
top toto titi tata
top toto titi tata
top toto titi tata
top toto titi tata
top toto titi tata
top toto titi tata
top toto titi tata
top toto titi tata
top toto2 titi tata
top toto2 titi tata
top toto2 titi tata
top toto2 titi tata
top toto2 titi tata
top toto2 titi tata
top toto2 titi tata
top toto2 titi tata
top toto2 titi tata
top toto2 titi tata
top toto3 titi tata
top toto3 titi tata
top toto3 titi tata
top toto3 titi tata
top toto3 titi tata
top toto3 titi tata
top toto3 titi tata
top toto3 titi tata
top toto3 titi tata
top toto3 titi tata


Amusez-vous bien!

fonction_periodique.txt · Dernière modification: 2009/01/11 16:24 de tyrtamos

Outils de la page