Ist generator.next () in Python 3 sichtbar?


247

Ich habe einen Generator, der eine Serie generiert, zum Beispiel:

def triangle_nums():
    '''Generates a series of triangle numbers'''
    tn = 0
    counter = 1
    while True:
        tn += counter
        yield tn
        counter += + 1

In Python 2 kann ich folgende Aufrufe tätigen:

g = triangle_nums()  # get the generator
g.next()             # get the next value

Wenn ich jedoch in Python 3 dieselben zwei Codezeilen ausführe, wird der folgende Fehler angezeigt:

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

Die Loop-Iterator-Syntax funktioniert jedoch in Python 3

for n in triangle_nums():
    if not exit_cond:
       do_something()...

Ich konnte noch nichts finden, was diesen Verhaltensunterschied für Python 3 erklärt.

Antworten:


406

g.next()wurde umbenannt in g.__next__(). Der Grund dafür ist die Konsistenz: Spezielle Methoden wie __init__()und __del__()alle haben doppelte Unterstriche (oder "Dunder" in der aktuellen Umgangssprache) und .next()waren eine der wenigen Ausnahmen von dieser Regel. Dies wurde in Python 3.0 behoben. [*]

Aber anstatt anzurufen g.__next__(), verwenden Sie next(g).

[*] Es gibt andere spezielle Attribute, die dieses Update erhalten haben. func_nameIst jetzt __name__, usw.


Gibt es eine Idee, warum Python 2 die Dunder-Konvention für diese Methoden überhaupt vermieden hat?
— Rick unterstützt Monica

Das ist wahrscheinlich nur ein Versehen.
— Lennart Regebro

Was ist, wenn Sie __ str __ im Unterricht überschreiben? Ändert es str (obj) oder __str __ (obj)?
— NoName

@NoName Es gibt so etwas nicht __str__(obj), also verstehe ich die Frage nicht wirklich.
— Lennart Regebro

1
@NoName Ja, das tust du.
— Lennart Regebro

144

Versuchen:

next(g)

Schauen Sie sich diese übersichtliche Tabelle an , die die Unterschiede in der Syntax zwischen 2 und 3 zeigt, wenn es darum geht.


1
@ MaikuMori Ich habe den Link behoben (Warten auf Peer-Revision) (Die Site diveintopython3.org scheint nicht verfügbar zu sein. Die Mirror-Site diveintopython3.ep.io ist noch am Leben)
— Gecco

1
Der Link wurde wieder behoben. python3porting.com/differences.html ist übrigens vollständiger.
— Lennart Regebro

Gibt es eine Rechtfertigung für den Wechsel von einer Methode zu einer Funktion, die darüber hinaus g.next()eigentlich sein sollte g.__next__(), und wir brauchen etwas, das keine dumme Methode mit der Funktionalität von ist g.next()?
— TC Proctor

11

Wenn Ihr Code unter Python2 und Python3 ausgeführt werden muss, verwenden Sie die 2to3 Six- Bibliothek wie folgt :

import six

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

18
Dies ist nur dann erforderlich, wenn Sie Python-Versionen vor 2.6 unterstützen müssen. Python 2.6 und 2.7 haben die nexteingebaute Funktion.
— Mark Dickinson
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.