Как и автор исходной статьи, я собираюсь описывать практику, и немного теории, необходимой для осмысления этих самых практических действий.
В первую очередь следует определиться что мы хотим получить. Это прямо указано в исходной статье: нам нужны все картинки, которые больше определённого размера.
Теперь рассмотрим алгоритм, который нам необходимо воплотить для осуществления данной задачи.
1. Скачать картинку
2. Проверить её размеры
3. Запихать в исходный массив.
Это всё. Как бы нас ни пытался убедить в обратном уважаемый автор.
Теперь, для абстрагирования, нам следует искать фрагменты, которые мы, в теории, можем использовать в других местах.
Скачивание файла по url является таким фрагментом, поэтому есть смысл вынести его в отдельную функцию.
Проверка размеров — нет. Это специфичная функция, и вряд ли она нам где-нибудь ещё пригодится.
Не бойтесь проделывать эту классификацию. Если окажется, что мы ошиблись, и функцию нужно будет использовать где-то ещё, мы можем легко и быстро перенести её. По крайней мере для питона это утверждение верно.
Я считаю сомнительным пользу от вынесения автором функционала retry за пределы функции download. По сути, областей, в которых вам может понадобиться по-дятловски долбиться в одном направлении, больше и нет. По крайней мере программист разумный должен избавляться от таких эзотерических коридоров в иные измерения, потому что Адун его знает что оттуда может вылезти. Конечно, это зависит от специфики проекта, с которой я досконально не знаком, но берусь утверждать, что я прав в 95% случаев.
Что же делать? В первую очередь запихать реализацию retry внутрь функции download. Снаружи эти кишки, как я сказал выше, скорее всего никогда не понадобятся. Во вторую очередь следует сделать что-нибудь нехорошее с функцией filter, но об этом ниже.
Собственно, вторая крупная ошибка автора скорее относится к проектированию, чем к кодингу. Давайте подумаем, зачем нам нужен эксепшен ImageTooSmall? Он будет где-нибудь отлавливаться? Конечно, то, что мы сами отлавливаем созданное нами исключение, чтобы его проигнорировать, я не считаю веской причиной для его существования. Нужно всеми силами стараться избавиться от империтивщины. Вместо этого я предлагаю создать функцию, проверяющую размер картинки, и возвращающую либо дополненный список, либо исходный. Эта функция совместима с reduce, что сильно упростит нам жизнь.
А вот, собственно, код, который у нас должен получиться. Как и автор исходной статьи, сами функции download и filter_small_images я приводить не буду.
photos = reduce(filter_small_images, map(download, url), [])
ссылка на оригинал статьи http://habrahabr.ru/post/157691/
Добавить комментарий