IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Interrompre une fonction ou une boucle de manière intéractive.


Sujet :

Python

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 14
    Par défaut Interrompre une fonction ou une boucle de manière intéractive.
    Bonjour.

    Je cherche le moyen d'avoir en python une fonction ou un objet qui calcule ce qu'il a à calculer (par exemple une approximation de pi) et qui peut être arrêté par l'utilisateur à tout moment. Est-ce possible en utilisant la fonction input() (j'ai essayé avec le module threading mais je n'y parviens pas) ? Le calcul peut-il s'arrêter de lui même si l'espace mémoire n'est plus suffisant ?

    Merci.

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 681
    Par défaut
    Je cherche le moyen d'avoir en python une fonction ou un objet qui calcule ce qu'il a à calculer (par exemple une approximation de pi) et qui peut être arrêté par l'utilisateur à tout moment.
    Tel que vous l'écrivez, je ne pense pas
    J'entends par là que je ne connais pas d'API qui permette de 'stopper', 'suspendre' l'exécution d'un programme ou d'un thread de l'extérieur.

    Il faut écrire un bout de code qui va modifier l'état d'une variable exemple 'arrêt' et faire en sorte que de temps en temps, l'objet qui calcule regarde si arrêt est toujours 'False' avant de continuer.

    Le calcul peut-il s'arrêter de lui même si l'espace mémoire n'est plus suffisant ?
    Oui, mais ce n'est généralement pas très propre.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Ayant eu le même genre de pb à résoudre (calcul long dans un eval(), pouvant être arrêté à tout moment par l'utilisateur), je l'ai à peu près résolu en utilisant un thread de calcul et sys.settrace.

    Il y a quelques conditions, parce que settrace est plutôt conçu pour le débugging. Il permet d'interposer automatiquement une fonction entre chaque ligne de code python. Dans notre cas, cette fonction va tester une condition d'arrêt et si oui, va déclencher une exception qui permettra de terminer le thread. Cela ne semble pas ralentir de trop la vitesse de calcul.

    Le détail de ma solution est ici: http://python.jpvweb.com/mesrecettes...c_sys.settrace

    Tyrtamos

  4. #4
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Suite de mon message précédent.

    En relisant le message de wiztricks, je m'aperçois que j'ai déjà utilisé ce qu'il évoque. Lorsqu'on a codé une fonction longue, on peut effectivement interposer un test avec déclenchement d'une exception qui arrête le thread de calcul.

    Voilà ce que ça peut donner:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    # importations fonctionnellement nécessaires
    import threading
    import sys
     
    # importation seulement nécessaire pour l'exemple
    import time
    from math import sqrt
     
    ##################################################
    def calcultreslong():
        i=1L
        while i<10000000000L:
            x=sqrt(i)
            i+=1
            if calcul.arret:
                raise ValueError  (u"Arrêt du calcul demandé")
        return x
     
    ##################################################
    class Calcul(threading.Thread):
     
        def __init__(self):
            threading.Thread.__init__(self)
            self.arret=False # =variable pour porter l'ordre d'arrêter le thread
     
        def run(self):
            try:
                calcultreslong()            
            except ValueError:
                print u"%s" % sys.exc_info()[1]# affichage du message d'erreur
            # fin de run, donc fin du thread
     
        def stopcalcul(self):
            self.arret=True
     
    ##################################################
    print "Lancement du thread"
    calcul=Calcul()
    calcul.start()
    tps=time.time()
    while calcul.isAlive():
        if time.time()-tps > 5: # arrêt du thread au bout de 5 secondes
            calcul.stopcalcul()
        time.sleep(0.1)
    print "fin du thread"
    time.sleep(2)
    Cet exemple arrête le calcul au bout de 5 secondes, mais on pourrait utiliser un signal de l'utilisateur. Dans mon cas, c'était dans un programme graphique tkinter, et le signal d'arrêt était l'appui sur une touche. Dans le cas d'un programme en console, c'est un peu plus compliqué parce qu'il faut créer le code pour tester le clavier dans une boucle.

    A moins de récupérer le Controle-C dans un 'try except', ce qui pourrait donner quelque chose comme ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    print "Lancement du thread"
    calcul=Calcul()
    calcul.start()
    try:
        while calcul.isAlive():
            time.sleep(0.1)
    except KeyboardInterrupt:
        calcul.stopcalcul()
    print "fin du thread"
    time.sleep(2)
    Tyrtamos

Discussions similaires

  1. Appel d'une fonction dans une fonction d'une même classe
    Par script73 dans le forum Général Python
    Réponses: 3
    Dernier message: 06/03/2015, 10h18
  2. [PHP-JS] une fonction dans une fonction
    Par lodan dans le forum Langage
    Réponses: 6
    Dernier message: 25/06/2006, 19h14
  3. Réponses: 3
    Dernier message: 29/04/2006, 13h02
  4. Réponses: 3
    Dernier message: 16/01/2006, 16h02
  5. Réponses: 4
    Dernier message: 17/03/2004, 17h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo