2009-07-02 11 views
149

Ho un generatore che genera una serie, ad esempio:Generator.next() è visibile in python 3.0?

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 sono in grado di effettuare le seguenti chiamate:

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

tuttavia in 3,0 se eseguo le stesse due linee di codice che sto ottenendo il seguente errore:

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

ma, la sintassi del ciclo iteratore funziona a 3.0

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

Non ho ancora trovato nulla che spieghi questa differenza di comportamento per 3.0.

risposta

232

corretto, g.next() è stato rinominato in g.__next__(). La ragione di questo è di avere consistenza. Metodi speciali come __init__() e __del__ hanno tutti doppio trattino di sottolineatura (o "dunder" poiché è diventato popolare chiamarli ora) e .next() è una delle poche eccezioni a tale regola. Python 3.0 risolve questo. [*]

Ma invece di chiamare g.__next__(), come dice Paolo, utilizzare next(g).

[*] Ci sono altri attributi speciali che hanno ottenuto questa correzione, come gli attributi di funzione. Non più func_name, è ora __name__, ecc

+0

qualche idea per quale motivo Python 2 ha evitato la convenzione di Dunder per questi metodi in primo luogo? –

+0

Probabilmente è solo una svista. –

80

Prova:

next(g) 

Partenza this neat table che mostra le differenze di sintassi tra 2 e 3 quando si tratta di questo.

+1

@MaikuMori ho fissato il link (in attesa per il peer revisione) (Il sito http://diveintopython3.org sembra essere inattivo. Il sito mirror http://diveintopython3.ep.io è ancora attivo) – gecco

+1

Risolto il problema. http://python3porting.com/differences.html è più completo, btw. –

+0

Il collegamento è ancora rotto ... – Klik

7

Se il codice deve essere eseguito con python2 e python3, usa il 2to3 six biblioteca come questa:

import six 

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

Non c'è molto bisogno di questo a meno che non sia necessario supportare versioni di Python precedenti alla 2.6. Python 2.6 e 2.7 hanno la funzione built-in 'next'. –