Search
Write a publication
Pull to refresh

Comments 19

Добавлю ещё одну важную вещь. Часто функции хотят работать с итератором на входе. А пользователи хотят передавать туда что попало (коллекцию, словарь, итерейбл, итератор, etc). И есть трюк, который сделал мой код шелковистым:

for x in iter(argument):
 ...

Трюк тут состоит в том, что iter от iterator - это итератор (no-op), а iter от всего остального - это итератор по ним! Т.е. используя iter мы делаем функцию всеядной, готовой сожрать любой генератор, итерейбл, итератор, список, строку, set и т.д.

Конкретно в цикле for-in вызов iter писать нет смысла, оператор цикла сам итератор получит.

Да, у меня был код с next(), правда. И именно там iter в начале позволил получить инвариант.

Ну, если у вас код с next — то вызывать iter надо не столько для получения инварианта, сколько для запуска итерации.


Как-то слабо представляю код, который ожидает итератора, но для удобства может принимать и коллекции. Чаще всего логично что код ожидает коллекции, но для удобства может принять и итератор.

Это понятно. Очевидно, намеренно простой код используется для иллюстрации

Ваша лодка готова, капитан!

А зачем? И коллекции, и словари - они все и так iterables, для них всех и так можно использовать `for x in ...`.

Цель статьи не в документации протокола итераторов. Цель статьи показать как можно исcледовать объекты в Python методом черного ящика, делая маленькие выводы самостоятельно, чтобы сделать освоение языка более интересным и продуктивным. Это полезно для тех, кто только начинает изучать Python. Иными словами, целевая аудитория в первую очередь новички. Но за комментарий спасибо!

Лучшее объяснение этой темы, лично для меня, в книге "Python. К вершинам мастерства" Л. Рамальо, глава 14.

Полностью согласен! Более того, для меня это одна из интереснейших книг о Python в принципе. Но целью моей статьи было показать как можно производить исследовательскую активность для анализа объектов. На мой взгляд, это полезно для тех, кто только начинает изучать Python - так его изучение можно сделать продуктивнее и интереснее.

Как-то невежливо тыкать палкой в то что хорошо документировано

:) Зависит от целей. Цель статьи показать как можно исследовать объекты, чтобы изучение языка было более продуктивным и интересным. Целевая аудитория новички.

На моей ubuntu 20.04 я вижу, что размер объекта итератор, созданного на основе range, равен не 32 байта, а 48:
$ python -V
Python 3.9.2
$ uname -a
Linux joy 5.4.0-99-generic #112-Ubuntu SMP Thu Feb 3 13:50:55 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
$ python -c 'import sys; print(sys.getsizeof(range(0)))'
48
$ 

Это размер непосредственно объекта range - арифметической прогрессии (про это написанно в конце статьи), а не итератора.

А вот так будет сколько?

print(sys.getsizeof(iter(range(0))))

Прошу прощения, скопировал не ту строку:
$ python -c 'import sys; print(sys.getsizeof(iter(range(0))))'
48
$ 

Посмотрел на линуксе, действительно 48.

А на винде - 32.

Спасибо за информацию!

По-моему Вы немного все смешали в кучу и получили коллизию.

(зависимость рождаемости от количества гнезд аиста)

Смотрите 1) есть питоновский встроенный list. Который хранит ссылки на объекты, поэтому размер его не зависит от размеров объектов внутри.

2) list так же реализует внутри себя методы next, iter которые интерпретатор Питона

воспринимает как необходимость работы с ним как с итерируемым объектом

3) вы создаете итератор как ссылку на объект что и заложенов природе так как существует п2 а именно метод iter

То есть свойства итератора как неизменяемого по памяти в Вашем случае это частный случай

и не свойства итератора. Можно создать свой итератор который будет пухнуть при вызове метода next.

list НЕ реализует внутри себя методы next. Это легко проверить, вызвав my_list.__next__() или передав список в функцию next(). --> AttributeError: 'list' object has no attribute 'next'.

list лист, как итерабельный объект реализует метод __iter__, который возвращает каждый раз новый итератор. А вот именно итератор и реализует метод __next__. И ещё итератор реализует и метод __iter__, но возвращает сам себя (это для удобства сделано). Итерируемый объект (итераторы не берем во внимание т.к. они итерируемы только формально и для удобства) НЕ ДОЛЖНЫ реализовывать метод next - это приводит ко серьезным ошибкам (вроде того, что объект можно будет обойти лишь одноразово).

Есть в Python вполне конкретный патерн под названием Iterator. Про него я и писал. А если создать свой итератор и заставить его "распухать", то это получится сделать только потому что всё в питоне - объекты и с ними можно творить что хочешь.

Sign up to leave a comment.

Articles