¿Es generador.next() visible en Python 3.0?
-
21-08-2019 - |
Pregunta
Tengo un generador que genera una serie, por ejemplo:
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 puedo realizar las siguientes llamadas:
g = triangleNums() # get the generator
g.next() # get next val
sin embargo, en 3.0, si ejecuto las mismas dos líneas de código, aparece el siguiente error:
AttributeError: 'generator' object has no attribute 'next'
pero la sintaxis del iterador de bucle funciona en 3.0
for n in triangleNums():
if not exitCond:
doSomething...
Todavía no he podido encontrar nada que explique esta diferencia de comportamiento para 3.0.
Solución
Correcto, g.next()
ha sido renombrado a g.__next__()
.La razón de esto es la coherencia:Métodos especiales como __init__()
y __del__
todos tienen guiones bajos dobles (o "dunder" en la lengua vernácula actual), y .next()
Fue una de las pocas excepciones a esa regla.Esto se solucionó en Python 3.0.[*]
Pero en lugar de llamar g.__next__()
, como dice Paolo, usa next(g)
.
[*] Hay otros atributos especiales que han obtenido esta solución; func_name
, es ahora __name__
, etc.
Otros consejos
Probar:
next(g)
esta tabla ordenada que muestra las diferencias en la sintaxis de entre 2 y 3 cuando se trata de esto.
Si el código se debe ejecutar con python2 y python3, utilice el 2to3 seis biblioteca como esto :
import six
six.next(g) # on PY2K: 'g.next()' and onPY3K: 'next(g)'