Есть ли способ отличить guish этот итератор от этого генератора? - PullRequest
0 голосов
/ 27 мая 2020

Мне известен этот вопрос:

Разница между генераторами и итераторами Python

Это более широко и менее технически обосновано. И ни один из ответов не был выбран. Я также прочитал эти ответы и, за одним возможным исключением, не нашел то, что искал. Я хочу sh задать более точный вопрос, чтобы помочь мне понять некоторые детали.

Я задал этот вопрос ранее:

В чем разница между иттератором python и a python generator?

Возможно, название или способ, которым я задал вопрос, вводили в заблуждение, поскольку полученный мной ответ не соответствовал моим намерениям, и вопрос был закрыт в считанные секунды.

Итак, я попытаюсь уточнить здесь.

Рассмотрим следующий код:

p = [k for k in range(1,1000)]
i = iter(p)
g = (k for k in p)

Есть ли какая-то операция, которая может быть выполнена с i и g, которая будет различать guish между этими двумя конструкциями. Что-то, что я могу сделать с i, что я не могу сделать с g, и тому подобное. Их тип выглядит как итератор списка по сравнению с объектом-генератором, но мне неясно, имеет ли это какое-либо прагматическое c влияние на то, что с ним можно делать, или на его эффективность. Я намеренно сначала составил список, чтобы подчеркнуть, что вопрос создания списка заранее или по требованию не в том, о чем идет речь. this - генераторы являются частным случаем итераторов, и все, что вы можете делать с построением генератора, используя либо понимания, либо yield, можно сделать, явно написав соответствующий итератор. Обоснование использования генератора, а не итератора, состоит в том, что иногда его проще писать. 1028 * Как написать класс генератора?

Ответы [ 2 ]

2 голосов
/ 27 мая 2020

Вот некоторые выдержки из документации:

4.5.1 Тип генератора: Генераторы Python предоставляют удобный способ реализации протокола итератора.

и более поздних версий:

6.2.9. Выражения доходности: Когда вызывается функция генератора, она возвращает итератор, известный как генератор.

=> функция генератора создает итератор

В следующих абзацах приводятся дополнительные методы генератора:

6.2.9.1. Генератор-итераторные методы В этом подразделе описаны методы итератора генератора.

generator.__next__(): ...

то же поведение, что и iterator.next()

generator.send(value) Возобновляет выполнение и «отправляет» значение в функцию генератора ...

`generator.throw (type [, value [, traceback]])` Вызывает исключение типа типа в точке, где генератор был приостановлен, и возвращает следующее значение, полученное функцией генератора ...

generator.close() Вызывает GeneratorExit в точке, где функция генератора была приостановлена ​​...

Это означает, что генератор является частным случаем итератора с некоторыми дополнительными методами.

2 голосов
/ 27 мая 2020

g поддерживает send, как и все генераторы, а i - нет. (send переход к g не является полезным , но вы можете это сделать.)

>>> g.send(None)
1
>>> i.send(None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list_iterator' object has no attribute 'send'

Вы также можете throw исключения в g или close это, чего нельзя сделать с i.

i можно мариновать, а g нельзя.

Кроме того, вы можете делать все, что угодно явных проверок и самоанализа, чтобы различить guish их. Проверка типов, изучение вывода str, поиск атрибутов, которые существуют только на одном или другом (например, g.gi_frame), и т. Д. c.

По большей части это детали реализации или случайные, а не то, что вы должны понимать как «разницу между генераторами и итераторами». Генераторы - это своего рода итераторы.

...