Является ли generator.next() видимым в python 3.0?
У меня есть генератор, который генерирует ряд, например:
def triangleNums():
'''generate series of triangle numbers'''
tn = 0
counter = 1
while(True):
tn = tn + counter
yield tn
counter = counter + 1
в python 2.6 Я могу сделать следующие вызовы:
g = triangleNums() # get the generator
g.next() # get next val
однако в 3.0, если я выполняю те же две строки кода, я получаю следующую ошибку:
AttributeError: 'generator' object has no attribute 'next'
но синтаксис цикла итератора работает в версии 3.0
for n in triangleNums():
if not exitCond:
doSomething...
Я еще не смог найти ничего, что объясняет эту разницу в поведении для 3.0.
Ответы
Ответ 1
Правильно, g.next()
переименовано в g.__next__()
. Причиной этого является постоянство. Специальные методы, такие как __init__()
и __del__
, имеют двойные символы подчеркивания (или "dunder", поскольку они становятся популярными, чтобы называть их сейчас), а .next() является одним из немногих исключений из этого правила. Python 3.0 исправляет это. [*]
Но вместо вызова g.__next__()
, как говорит Паоло, используйте next(g)
.
[*] Есть более специальные атрибуты, которые получили это исправление, например, атрибуты функции. Больше func_name
, теперь он __name__
и т.д.
Ответ 2
Try:
next(g)
Отметьте эту опрятную таблицу, которая показывает различия в синтаксисе между 2 и 3, когда дело доходит до этого.
Ответ 3
Если ваш код должен работать под Python2 и Python3, используйте библиотеку 2to3 six:
import six
six.next(g) # on PY2K: 'g.next()' and onPY3K: 'next(g)'