2009-07-02 14 views
149

Tengo un generador que genera una serie, por ejemplo:¿Está el generador.next() visible en 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 Soy capaz de realizar las siguientes llamadas: sin embargo

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

en 3.0 si ejecuto las mismas dos líneas de código que estoy consiguiendo el error siguiente:

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

pero, la sintaxis iterador de bucle funciona en 3.0

for n in triangleNums(): 
    if not exitCond: 
     doSomething... 

No he podido encontrar nada aún que explique esta diferencia de comportamiento para 3.0.

Respuesta

232

Correcto, g.next() se ha cambiado el nombre a g.__next__(). La razón para esto es tener consistencia. Los métodos especiales como __init__() y __del__ tienen doble guión bajo (o "dunder", ya que se está volviendo popular llamarlos ahora), y .next() es una de las pocas excepciones a esa regla. Python 3.0 corrige eso. [*]

Pero en lugar de llamar al g.__next__(), como dice Paolo, use next(g).

[*] Hay más atributos especiales que han recibido esta corrección, como atributos de funciones. Ya no func_name, ahora __name__, etc.

+0

¿Alguna idea de por qué python 2 evitó la convención dunder para estos métodos en primer lugar? –

+0

Eso es solo un descuido. –

80

Probar:

next(g) 

Salida this neat table que muestra las diferencias en la sintaxis de entre 2 y 3 cuando se trata de esto.

+1

@MaikuMori que fija el enlace (a la espera de la revisión por pares) (El sitio http://diveintopython3.org parece estar fuera de servicio. Mirror site http://diveintopython3.ep.io todavía está activo) – gecco

+1

Se ha reparado el enlace nuevamente. http://python3porting.com/differences.html es más completo, por cierto. –

+0

El enlace aún está roto ... – Klik

7

Si el código se debe ejecutar con python2 y python3, utilice el 2to3 six biblioteca de la siguiente manera:

import six 

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

No hay mucha necesidad de esto a menos que necesite admitir versiones de Python anteriores a la 2.6. Python 2.6 y 2.7 tienen la función 'next' incorporada. –

Cuestiones relacionadas