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 :

Souci avec l'emploi de yield


Sujet :

Python

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Par défaut Souci avec l'emploi de yield
    Bonjour à tous,

    Je viens de me pencher sur le module itertools et dans la doc Pyrhon, j'y trouve des yield à profusion...
    J'ai décidé de tester les exemples proposés...
    Et là, ça commence mal.
    1er exemple (code obtenu ici : http://docs.python.org/library/itertools.html), 1er problème.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def chain(*iterables):
        # chain('ABC', 'DEF') --> A B C D E F
        for it in iterables:
            for element in it:
                yield element
    Et moi d'en conclure - bêtement - que si je tape chain('ABC', 'DEF') en ligne de commande, je vais obtenir A B C D E F...
    Vous, ça ne va pas vous surprendre, moi, si !
    Voilà mes essais :
    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
    >>> chain('ABC', 'DEF')
    <generator object chain at 0x011BE1C0>
    >>> chain('ABC', 'DEF').next()
    'A'
    >>> for i in range(6):
    	chain('ABC', 'DEF')
     
     
    <generator object chain at 0x011BE2D8>
    <generator object chain at 0x011BE0F8>
    <generator object chain at 0x011BE1C0>
    <generator object chain at 0x011BE2D8>
    <generator object chain at 0x011BE0F8>
    <generator object chain at 0x011BE1C0>
    >>> for i in range(6):
    	print chain('ABC', 'DEF').next()
     
     
    A
    A
    A
    A
    A
    A
    Les autres exemples sont encore plus intéressants, mais pour chacun, je me heurte au même problème.
    Je pense que c'est dû à l'emploi de yield, parce que si je remplace yield par return :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >>> chain('ABC', 'DEF')
    'A'
    Et d'ailleurs pourquoi y a-t-il un affichage ? Il n'y a de print nulle part !?

    Merci de m'éclairer.

    @+

  2. #2
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Non, à chaque fois que tu fais chaine('ABC', 'DEF'), tu crées un nouvel itérateur (un nouvel objet, comme le montrent les différentes adresses mémoire obtenues, 0x011BE2D8, 0x011BE0F8, 0x011BE1C0, etc.), qui est évidemment toujours initialisé sur le premier élément.

    Pour utiliser un itérateur, il ne faut pas faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for i in range(6):
        print(chaine('ABC', 'DEF'))
    …Mais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for e in chaine('ABC', 'DEF'):
        print(e)
    Un itérateur (et toute fonction utilisant yield peut servir d’itérateur) est une sorte de liste qui se construit au fur et à mesure, si tu veux (et que tu ne peux parcourir qu’une seule fois).

    Quand à l’affichage, dans une console python, à chaque fois qu’une expression génère un résultat non “capturé” (par une assignation ou autre), ce résultat est affiché (un genre de print tacite, quoi –*à ceci près que c’est __repr__ qui est utilisé, et pas __str__…).

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Par défaut
    Salut,

    Belle réactivité...
    Merci
    Ok, j'ai testé aussi avec les autres exemples ça marche nickel...

    Il va falloir que je me repenche sur yield, je pensais avoir saisi : il semble que non...
    yield fait du "coup par coup", si je remplace alors yield par return alors je n'ai plus que l'affichage de "A" et tout s'arrête.
    Il y a pourtant bien une boucle (même trois : une dans l'appel, deux dans la fonction) !?...

    Merci encore

    @+

  4. #4
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Vi, mais boucle ou pas boucle, return termine la fonction et retourne la valeur qui lui est fournie (implicitement None, si absente). Au passage, une fonction retournant toujours quelque chose en python, le return est implicite à la fin de celles qui n’en ont un explicite.

    C’est justement tout l’intérêt de yield*: il permet de “retourner” une valeur sans sortir de la fonction. En interne, python convertit une fonction faisant usage de yield en un générateur qui, à chaque appel de next(), exécute le code de la fonction jusqu’au premier yield rencontré, puis la “met en pause” jusqu’au next() suivant…

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Par défaut
    Bonsoir,

    ok ! merci !

    @+

Discussions similaires

  1. quelques soucis avec word 2000
    Par ramchou dans le forum Word
    Réponses: 3
    Dernier message: 06/09/2004, 18h13
  2. SOucis avec une reequete imbriquee
    Par Ni4k dans le forum Langage SQL
    Réponses: 6
    Dernier message: 30/03/2004, 08h56
  3. souci avec un algorithme
    Par slider16 dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 22/03/2004, 17h17
  4. [DEBUTANT] petits soucis avec un prgm de chat
    Par LechucK dans le forum MFC
    Réponses: 8
    Dernier message: 19/01/2004, 16h52
  5. Réponses: 4
    Dernier message: 16/02/2003, 12h16

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