Виден ли генератор.next() в Python 3.0?
-
21-08-2019 - |
Вопрос
У меня есть генератор, который генерирует ряд, например:
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.
Решение
Правильный, g.next()
был переименован в g.__next__()
.Причиной этого является последовательность:Специальные методы, такие как __init__()
и __del__
все они имеют двойное подчеркивание (или «дандер» на современном языке) и .next()
был одним из немногих исключений из этого правила.Это было исправлено в Python 3.0.[*]
Но вместо того, чтобы позвонить g.__next__()
, как говорит Паоло, используйте next(g)
.
[*] Исправлены и другие специальные атрибуты; func_name
, сейчас __name__
, и т. д.
Другие советы
Пытаться:
next(g)
Проверить этот аккуратный стол это показывает различия в синтаксисе между 2 и 3, когда дело доходит до этого.
Если ваш код должен работать под управлением Python2 и Python3, используйте команду 2to3. шесть библиотека такая:
import six
six.next(g) # on PY2K: 'g.next()' and onPY3K: 'next(g)'