2009-07-02 22 views
149

Mam generator, który generuje szereg, na przykład:Czy generator.next() jest widoczny w pythonie 3.0?

def triangleNums(): 
    '''generate series of triangle numbers''' 
    tn = 0 
    counter = 1 
    while(True): 
     tn = tn + counter 
     yield tn 
     counter = counter + 1 

w Pythonie 2.6 Jestem w stanie wykonać następujące połączenia:

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

jednak w 3,0 gdybym wykonać te same dwie linie kodu dostaję następujący błąd:

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

ale składnia pętli iteracyjnej działa w 3,0

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

Nie udało mi się znaleźć niczego, co tłumaczy tę różnicę w zachowaniu w wersji 3.0.

Odpowiedz

232

Poprawnie, g.next() zmieniono na g.__next__(). Powodem tego jest zgodność. Specjalne metody, takie jak __init__() i __del__, mają podwójne podkreślenia (lub "dunder", ponieważ popularne stają się nazywanie ich teraz), a .next() jest jednym z nielicznych wyjątków od tej reguły. Python 3.0 to naprawi. [*]

Ale zamiast dzwonić pod numer g.__next__(), jak mówi Paolo, użyj next(g).

[*] Istnieje więcej specjalnych atrybutów, które uzyskały tę poprawkę, podobnie jak atrybuty funkcji. Już func_name, to teraz __name__ itp

+0

jakikolwiek pomysł, dlaczego Python 2 wyeliminował konwencję dunder dla tych metod w pierwszej kolejności? –

+0

To prawdopodobnie tylko niedopatrzenie. –

80

Spróbuj:

next(g) 

Wyjazd this neat table który pokazuje różnice w składni między 2 i 3, jeśli chodzi o to.

+1

@MaikuMori Poprawiłem link (oczekiwanie na zmiany peer) (Wydaje się, że strona http://diveintopython3.org jest niedostępna. Http://diveintopython3.ep.io jest nadal żywa) – gecco

+1

Naprawiono link ponownie. http://python3porting.com/differences.html jest bardziej kompletny, btw. –

+0

Łącze nadal jest uszkodzone ... – Klik

7

Jeśli Twój kod musi działać pod python2 i Python3 użyj 2to3 six biblioteka tak:

import six 

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

Nie ma takiej potrzeby, chyba że potrzebujesz obsługi wersji Pythona wcześniejszych niż 2.6. Python 2.6 i 2.7 mają wbudowaną funkcję 'next'. –