J'ai un générateur qui génère une série, par exemple:
def triangleNums():
'''generate series of triangle numbers'''
tn = 0
counter = 1
while(True):
tn = tn + counter
yield tn
counter = counter + 1
in python 2.6 Je peux effectuer les appels suivants:
g = triangleNums() # get the generator
g.next() # get next val
cependant, dans la version 3.0, si j'exécute les deux mêmes lignes de code, l'erreur suivante apparaît:
AttributeError: 'generator' object has no attribute 'next'
mais la syntaxe d'itérateur de boucle fonctionne dans la version 3.0
for n in triangleNums():
if not exitCond:
doSomething...
Je n'ai encore rien trouvé qui explique cette différence de comportement pour la version 3.0.
Correct, g.next()
a été renommé en g.__next__()
. La raison en est la cohérence: des méthodes spéciales telles que __init__()
et __del__
Ont toutes des doubles tirets bas (ou "dunder" dans la langue courante), et .next()
était l'un des les quelques exceptions à cette règle. Ce problème a été résolu dans Python 3.0. [*]
Mais au lieu d'appeler g.__next__()
, comme le dit Paolo, utilisez next(g)
.
[*] Il existe d'autres attributs spéciaux qui ont obtenu ce correctif; func_name
, Est maintenant __name__
, Etc.
Essayer:
next(g)
Découvrez ce tableau soigné qui montre les différences de syntaxe entre 2 et 3 à ce sujet.
Si votre code doit être exécuté sous Python2 et Python3, utilisez la bibliothèque 2to3 six comme ceci:
import six
six.next(g) # on PY2K: 'g.next()' and onPY3K: 'next(g)'