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 :

break dans une boucle for


Sujet :

Python

  1. #1
    Membre éprouvé
    Homme Profil pro
    Vagabong étudiant en annalyse du signal.
    Inscrit en
    Avril 2019
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Vagabong étudiant en annalyse du signal.
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2019
    Messages : 134
    Par défaut break dans une boucle for
    Voici la méthode d'une classe héritée de threading.Thread. Cette méthode est appelée dans un for de la méthode run() asynchrone.

    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
    def _next_timestamp(self) -> Fraction:
        """Return the next timestamp to be decoded."""
        while True:
            for timestamp in sorted(set(map(Fraction, self._predictor.predict(PRED_BUFFER)))):
                print("timestamp predit", timestamp)
                if self._stop_flag:
                    return StopIteration
                try:
                    yield self._queues["request"].get_nowait()
                    print("break")
                    break  # if a new timestamp in the predictor, reset the prediction
                except queue.Empty:
                    if timestamp not in self._frames:
                        print(timestamp, "n'est pas dans la queue")
                        yield timestamp
                    else:
                        print(timestamp, "deja dans la queue")
            else:
                print("prediction terminee")
                yield self._queues["request"].get()
    Bon, ou est le problème me diriez vous? Et bien voici ce qui se passe quand on l'appelle:

    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
    >>> frame_anticipator = FrameAnticipator(video, 0, {})
    >>> 
    >>> timestamp predit 0
                          0 n'est pas dans la queue
                                                   prediction terminee
     
    >>> frame_anticipator.snapshot(Fraction(0))
    <av.VideoFrame, pts=0 yuv420p 1280x720 at 0x71ef653cbbe0>
    >>> frame_anticipator.snapshot(Fraction(1))
    <av.VideoFrame, pts=968 yuv420p 1280x720 at 0x71ef653cbc40>
    >>> timestamp predit 0
                          0 deja dans la queue
                                              prediction terminee
     
    >>> frame_anticipator.snapshot(Fraction(2))
    <av.VideoFrame, pts=1969 yuv420p 1280x720 at 0x71ef653cb400>
    >>>
    Jusque-là, le comportement est tout à fait attendu. Mais voyez ce que le code continue à m'afficher à l'infini juste après :
    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
    timestamp predit 4
                          4 n'est pas dans la queue
                                                   timestamp predit 8
                                                                     8 n'est pas dans la queue
                                                                                              timestamp predit 562949953421313/35184372088832
                       562949953421313/35184372088832 n'est pas dans la queue
                                                                             timestamp predit 4
                                                                                               4 deja dans la queue
                                                                                                                   timestamp predit 8
               8 deja dans la queue
                                   timestamp predit 562949953421313/35184372088832
                                                                                  562949953421313/35184372088832 n'est pas dans la queue
                  timestamp predit 4
                                    4 deja dans la queue
                                                        timestamp predit 8
                                                                          8 deja dans la queue
                                                                                              timestamp predit 562949953421313/35184372088832
                       562949953421313/35184372088832 n'est pas dans la queue
                                                                             timestamp predit 4
                                                                                               4 deja dans la queue
    ...
    Et cela a l'infinie !

    Pourquoi diable n'entre-t-il pas dans le else du for, alors que break n'est jamais atteint !?

  2. #2
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 329
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 329
    Par défaut
    bonjour

    code trop compliqué ...

    Il te suffit d'un mini script pour comprendre que fait le else avec for:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for i in range(12):
        print(i)
        if i > 5:
            break
    else:
        print("sortie de boucle")
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for i in range(12):
        print(i)
        #if i > 5:
        #    break
    else:
        print("sortie de boucle")
    Et cela a l'infinie
    peut-être logique avec ton while True ? ta seule sortie est self._stop_flag ?
    $moi= (:nono: !== :oops:) ? :king: : :triste: ;

  3. #3
    Membre éprouvé
    Homme Profil pro
    Vagabong étudiant en annalyse du signal.
    Inscrit en
    Avril 2019
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Vagabong étudiant en annalyse du signal.
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2019
    Messages : 134
    Par défaut
    Pardon, il manque en effet un élément:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self._queues["request"].get()
    est bloquant.
    Mais la question n'est pas : pourquoi ça affiche des choses à l'infinie (en effet, ça vient du while True et c'est normal).
    Justement, si ça tourne en rond à l'infini, ca veut bien dire que la boucle for est appelé plusieurs fois, et donc qu'elle termine à un moment.
    Mais comment la boucle for termine-t-elle? En effet, les 2 seuls points de sorties sont "break" et "else", or les prints nous montrent que ni l'un ni l'autre n'est jamais appelé!
    Un autre point de sortie pourrait être une exception, mais ce n'est pas non plus le cas, car l'exception arrêterait le while True...

    Le mystère reste donc toujours entier.

  4. #4
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 083
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 083
    Par défaut
    Pourquoi pas mettre un print avanr le return StopIteration pour voir, personne je trouve que c'est pas très propre de quitter le while True de cette façon.

  5. #5
    Membre éprouvé
    Homme Profil pro
    Vagabong étudiant en annalyse du signal.
    Inscrit en
    Avril 2019
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Vagabong étudiant en annalyse du signal.
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2019
    Messages : 134
    Par défaut
    J'aurais du retirer le test du self._stop_flag, qui n'est jamais atteint, car cet attribut est toujours a False. (Il n'y a pour le moment aucun endroit dans le code qui le modifie).

  6. #6
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 083
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 083
    Par défaut
    "prediction terminee" n'étant pas affiché je suppose que ça break à un moment , perso j'aurais mis le print en fin de boucle après le else.
    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
    def _next_timestamp(self) -> Fraction:
        """Return the next timestamp to be decoded."""
        while True:
            for timestamp in sorted(set(map(Fraction, self._predictor.predict(PRED_BUFFER)))):
                print("timestamp predit", timestamp)
                try:
                    yield self._queues["request"].get_nowait()
                    break  # if a new timestamp in the predictor, reset the prediction
                except queue.Empty:
                    if timestamp not in self._frames:
                        print(timestamp, "n'est pas dans la queue")
                        yield timestamp
                    else:
                        print(timestamp, "deja dans la queue")
            else:
                print("prediction terminee")
                yield self._queues["request"].get()
                continue
            print("break")

  7. #7
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 749
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 749
    Par défaut
    Hello,

    On peut voir l'implémentation de _predictor ?
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

Discussions similaires

  1. Problème d'instruction break dans une boucle for
    Par Rony Rauzduel dans le forum Langage
    Réponses: 11
    Dernier message: 16/10/2015, 14h56
  2. Shell - Erreur dans une boucle for
    Par claralavraie dans le forum Linux
    Réponses: 4
    Dernier message: 11/01/2006, 14h45
  3. Problème avec une DLL dans une boucle For
    Par BraDim dans le forum Langage
    Réponses: 5
    Dernier message: 20/09/2005, 13h22
  4. [batch] incrémentation dans une boucle for
    Par bart64 dans le forum Scripts/Batch
    Réponses: 4
    Dernier message: 08/09/2004, 21h05
  5. Réponses: 3
    Dernier message: 06/07/2004, 11h21

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