Pull to refresh

Comments 22

Правильно ли я понимаю, что автор, в большинстве примеров, заменяет большую, но легкочитаемую конструкцию, на короткую, но трудночитаемую, без какого-то профита?

при этом периодически заменяет явное предвычисление значительных объемов данных на ленивую обработку когда-нибудь потом и не всего

Помню, коллега-аналитик, как-то спрашивал совета, что лучше сделать(просто потому что я под рукой оказался). Что во время его функций обработки данных из базы, СУБД коннект закрывает. Через пол-суток.

На вопрос, какой объём данных он считывает из базы, он ответил, что мегабайт 100-200, не больше. А функции обработки дёргали ещё апишки всякие и т.д., вот и занимало много времени.

Вот вам и ленивая обработка, с yield

Согласен, что стилистика кода меняется. Становится ли труднее читать — не уверен. Предлагаю рассматривать мой вариант написания, как некий DSL. Поначалу нечитаемо, после привыкаешь.
По поводу профита — генератор позволяет отложить вычисление на неопределённый срок и не занимать все это время память. Вот и весь профит.

Одна большая операция займет меньше времени, чем много маленьких. Итератор итератору рознь. Буду честным, я не знаю, какой код будет сгенерирован интерпретатором при использовании итератора, но если прибегнуть напрямую к ассемблеру, то обычный цикл будет на порядок быстрее работать, чем постоянные вызовы итератора. Перекладывание стека с места на место и т.д. Цикл в асм выглядит очень просто, а использование итератора - это множественные вызовы другого куска кода со всеми вытекающими (сохранение стека, выполнение кода, возвращение стека)

Я сам из Мира Ассемблера пришел, и, поначалу, году эдак в 2012-2014, генераторы мне казались одной из бесполезных штук в Python. После я подсел на Dabeaz, и его гениальные презентации о генераторах, корутинах, корпоративную многозадачность и т.п. Конечно, я фанат его Curio, поскольку понял, насколько это круче asyncio. Так вот, если полагаться на его замеры из 2009, то генератор не сильно проигрывает циклу. Презентация coroutines, слайд 51. На следующих слайдах он почти сокращает отставание.
Выигрыш проявится совсем не в этом месте. В REST представлении, например, надо сереализовать полмиллиона точек и отдать пользователю. Я могу их подготовить заранее в list/tuple. В случае с генератором — генерация точек запланирована, но не выполнена. И тут, если что то после пойдет не так, я выброшу 427 exception. В итоге ответ 427 пришел пользователю быстрее в случае с генератором.

Можно подробнее про пример с полмиллионом точек?
1) Это стриминг или классический ответ с данными на запрос?
2) Что такое 427? В HTTP статус-кодах гуглится как unassigned.
3) Не понял, почему мы в цикле не можем сразу рейзить ошибку? (хотя, конечно, try except вставлять в итерацию в любом случае не лучшее решение) Или что тут имеется ввиду?

  1. REST. вопрос-ответ, в ответе schape(фигура) для карты высокой точности. про полмиллиона приврал, максимум 17 тысяч точек.
  2. 427 — unprocessable entity. Это когда все верно на входе, например запрошено пересечение искомого шейпа с шейпом, Пересечение ищет Postgis. нет ошибки расчета, но ответ не соответствует ожидаемому. например: шейпы пересекаются в одной точке. точка это не плоскость пересечения. Для плоскости минимум три точки надо. Потому не получается вернуть фигуру, а только ее частный случай прямая или точка. Мы маркируем такой ответ как 427. Хотя можно было бы писать, не найдено пересечений, но найдены граничные области. Вопрос вкуса.
  3. В случае обсчета объемов/плоскостей невозможно по одной точке понять что есть ошибка. А так то — Exception хорошее решение, EAFP в питоне это норм практика.

2) 422
2.5) Стало очень интересно, что за задача на входе и что за тип данных, где так принципиально иметь больше 1 точки в качестве пересечения, просто представил полигоны и там обычно в пересечении тоже полигон ... (без снобизма, реально интересно, для общего развития, так сказать)
3) Я всё-таки не понял, в чём тут разница между примененияем генератора и применением цикла? Если и там и там нам надо сперва посчитать, почему пользователь ошибку увидит раньше?

  1. Принимается, 422. Попутал
  2. Все верно. Линия и точка это полигон нулевой площади. Можно вернуть пользователю полигон нулевой площади. И отрисовать его. Или обработать на клиенте и выдать ошибку. А можно вернуть ошибку с сервера. Задача то простая для менеджера. Нарисовал виноградник на карте, порверил, что DOC совпадает. не совпала — выдал ошибку, совпала — выдал DOC.
  3. Вероятно решить можно проще и без генераторов. Надо еще подумать.

Отличный стиль, очень увлекательно, но с читаемостью проблемы. А стоит ли улучшать не критичный код?

Задачи рефакторинга, как таковой, тут не стоит. Когда весь проект станет генератором — самому захочется даже мелочи поправить.

В примере где используется generator.close() в последней строке я не нашел закрывающую фигурную скобку, или так надо?

Конечно в статье есть много спорных утверждений, но хотел сказать другое!

Спасибо автору за его контент, на хабре который тонет в переводах, и корпоративных статьях не хвататет такого оригинального и настоящего контента. Прочитал с удовольвствием, где то узнал себя, коллег. Где то порадовался, что тоже так делаю, а где то увидел, что "О, так же можно было, но уже ничего не вернуть и не переписать".

На счет нечитаемости генераторов Мне кажется по началу только конструкция с or может вызвать проблемы, а с pipelines так вообще только лучше становится.

Спасибо. Такие отзывы мотивируют писать еще.

Статья хорошая, поднимает интересную проблему. Как писать код на питоне, когда есть варианты.

К сожалению, есть довольно-таки много разработчиков-питонистов, которые придерживаются схожей с автором точки зрения. Я бы охарактеризовал эту точку зрения примерно так:

Я выучил новую языковую конструкцию, буду теперь пихать ее везде и всюду.

Я использовал языковую конструкцию, которая позволяет запихнуть в одну строку то, что обычный цикл делает в несколько строк. Ура! Теперь мой код чище.

Моя точк зрения по этому вопросу. Главное в коде читаемость. И одна из главных фишек питона, это отступы, которые вместе с циклами гарантируют хороший уровень читабельности кода. Вот например:

while True:
  if a:
    break

Говорят, что если это заменить одной строкой, будет будет чище. А читабельность, ну что же, можно привыкнуть.
Я не хочу привыкать. Я хочу читать код, охватывать блоки кода одним взглядом и думать над тем, что он делает. А вместо этого предлагают читать каждую сторчку, расшифровывать ее, пытась понять, как она делает. Лично я расшифровав какую-нибудь строчку, уже забываю, зачем я ее начал расшифоровывать.

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

Тоже не понимаю, зачем сокращать количество строк, ради "чистоты". KISS же

На днях как раз колупался в коде, где в строку было map/filter/reduce, приправленное join(tuple(filter(lambda

Причём, timeit показал, что оно ещё и работает медленнее, написанного в человекочитаемом виде.Хотя, может, timeit врёт, конечно.

Проверил, сработает без tuple


template.join(filter(lambda

И сработает так же без filter


template.join(bit for bit in iterable if lambda(bit))

Теперь должно работать быстро.


Человекочитаемость у всех своя, так тоже работает:


template.join(
    bit for bit in iterable 
         if lambda(bit)
)

Они не Пупа и Лупа. Они Пупу и Лупу. Именно поэтому Пупу получает не зарплату, а то, что он получает. Потому что фамилии эти не склоняются. Потому что это молдавские фамилии.

А за статью спасибо, статья правильная. Генераторы начинающим часто кажутся сложнее, чем они есть. Зато когда их распробуешь, потом невозможно отказаться.

Cпасибо, согласен, что после привыкания к генераторам уже по другому сложно думать!


А я и не знал, что умпалумпы из Молдавии. Надо поправить в википедии!

Sign up to leave a comment.

Articles