2009-07-02 6 views
149

J'ai un générateur qui génère une série, par exemple:Est-ce que generator.next() est visible dans python 3.0?

def triangleNums(): 
    '''generate series of triangle numbers''' 
    tn = 0 
    counter = 1 
    while(True): 
     tn = tn + counter 
     yield tn 
     counter = counter + 1 

en python 2.6 Je suis capable de faire les appels suivants:

g = triangleNums() # get the generator 
g.next()   # get next val 

cependant dans la version 3.0 si j'exécute les mêmes deux lignes du code que je reçois l'erreur suivante:

AttributeError: 'generator' object has no attribute 'next' 

mais la syntaxe boucle de iterator fonctionne dans la version 3.0

Je n'ai encore rien trouvé qui explique cette différence de comportement pour 3.0.

Répondre

232

Correct, g.next() a été renommé g.__next__(). La raison en est d'avoir la consistance. Les méthodes spéciales comme __init__() et __del__ ont toutes deux traits de soulignement doubles (ou "dunder" car il est de plus en plus courant de les appeler maintenant), et .next() est l'une des rares exceptions à cette règle. Python 3.0 corrige cela. [*]

Mais au lieu d'appeler g.__next__(), comme le dit Paolo, utilisez next(g).

[*] D'autres attributs spéciaux ont obtenu ce correctif, comme les attributs de fonction. Non plus func_name, il est maintenant __name__, etc.

+0

une idée de pourquoi python 2 esquivé la convention dunder pour ces méthodes en premier lieu? –

+0

C'est probablement juste un oubli. –

80

Essayez:

next(g) 

Découvrez this neat table qui montre les différences de syntaxe entre 2 et 3 en ce qui concerne ce sujet.

+1

@MaikuMori Je fixe le lien (en attente de révision par les pairs) (Le site http://diveintopython3.org semble être en panne.Le site miroir http://diveintopython3.ep.io est toujours en vie) – gecco

+1

Correction du lien à nouveau. http://python3porting.com/differences.html est plus complet, btw. –

+0

Le lien est toujours cassé ... – Klik

7

Si votre code doit être exécuté sous python2 et python3, utilisez la 2to3 bibliothèque six comme ceci:

import six 

six.next(g) # on PY2K: 'g.next()' and onPY3K: 'next(g)' 
+7

Il n'y a pas grand besoin de ceci à moins que vous ayez besoin de supporter les versions de Python antérieures à 2.6. Python 2.6 et 2.7 ont la fonction intégrée 'next'. –

Questions connexes