web-dev-qa-db-fra.com

Generator.next () est-il visible dans python 3.0?)?

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.

219
jottos

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.

363
Lennart Regebro

Essayer:

next(g)

Découvrez ce tableau soigné qui montre les différences de syntaxe entre 2 et 3 à ce sujet.

125
Paolo Bergantino

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)'
11
danius