Перевод статьи: Stop naming your python modules “utils”
Представьте себе следующую типичную ситуацию: разработчик, который либо добавляет новый код, либо реорганизует существующий, работая с каким нибудь новым классом или функцией. Ему нужно решать где разместит этот код, но он функционально не подходит к уже существующим модулям. И что же обычно делает разработчик в этой ситуации? Он создает новый модуль — utils.py.
Спонсор поста Блог о программирование — «Старая полка»:
В блоге вы найдете:
— Небольшой сборник софта за многие годы. Программы для Windows, DOS и браузера.
— Компьютерные советы и небольшие программы с пояснениями.
— Ссылки на софт.
Пример статьи:
Установка сертификата от Let’s Encrypt
Возможно, utils — одно из худших названий модуля, потому что оно очень размыто и неточно. Такое имя не говорит, какова цель кода. Напротив, модуль utils может содержать почти все что угодно. Присваивая имя utils модулю, разработчик устанавливает идеальные условия для создания несвязного кода. Поскольку имя модуля не говорит членам команды, подходит ли им то что внутри или нет, вполне вероятно, что в конечном итоге там появится много несвязанный кода. Подробнее об этом чуть позже.
Синонимы utils, таких как helpers, commons и т. д., так же являются плохим выбором по тем же причинам.
Изначально да — это может быть только одна функция. Одна функция в плохо названном модуле не так ли?
Как и в теории с разбитыми окнами (broken windows theory), одно из проявлений плохого поведения побуждает к большему. Одна функция или класс в utils — это небольшая проблема. Следовательно, это может быть реорганизовано, когда будет время. Как только модуль utils начнет расти, потребуется больше усилий для его разделения. И сюрприз, сюрприз, никто не захочет этого делать.
Насколько это плохо? Однажды в одном репозитории Python я увидел несколько модулей utils.py. Он содержал 13 различных функций и один служебный класс. Что делали эти функции? Все, от проверки и нормализации данных, до сохранения в базе данных, и отправки HTTP-запросов, а так же форматирование текущей даты и времени в соответствии с параметром формата (Да, это были отдельные, не к чему не привязанные функции).
def send_post_request(url, data, logger): ... def save_details(source_obj, override_data_from_source_obj: dict = None): ... def normalize_address(address: str) -> str:
Так выглядит ад программирования. utils.py быстро становится водоворотом для всего кода, который не подходит в другие места. Это плавно приводит нас к причине № 2 …
Действительно, может не быть места для нового класса / функции. Это нормальная реакция при создание нового кода. Однако программист должен приложить больше усилий, думая об имени модуля. Как мы знаем, самая легкая дорога с utils — это скользкий путь.
Мы можем добиться большего, назвав модуль по назначению функций, находящихся внутри. Если они будут создавать другие объекты, назовем его factories.py. Если их роль — валидация — используйте validators.py. Может быть, нам нужно несколько функций, которые работают с телефонными номерами? Посмотрите, не могут ли они быть обычным классом PhoneNumber с сохранением состояния и просто поместите его в отдельный файл — phone_number.py.
Особый случай — функции с бизнес-логикой. Для этого существует множество методов, некоторые из которых более сложны, чем другие, но давайте рассмотрим простой случай. Предположим, у нас есть веб-приложение Django + DRF, которое содержит бизнес-логику в сериализаторах. Мы медленно переносим наш API на версию 2, и нам нужно поместить бизнес-логику, извлеченную из сериализатора V1, в другое место, чтобы сериализатор V2 мог использовать это повторно. НЕ ОСТАВЛЯЙТЕ ЭТО В utils.py. Попробуйте поместить бизнес-логику в модуль services.py. Служба имен происходит из службы приложений — единственное, что приложение делает для клиентов. Если это, например, бронирование рейса, сервис может называться flight_booking_service и оно может:
Допустим, вы создаете распределенное приложение, и есть фрагменты кода, которые необходимо повторно использовать в большинстве или во всех микросервисах. Естественная реакция — собрать их вместе где-нибудь, например, в отдельный репозиторий, который будет установлен как пакет. Но, пожалуйста, не называйте это {company_name}-utils. Я слышал о случае такого хранилища, но, к счастью для его сопровождающих, он был не таким уж большим. Он содержал код, отвечающий за:
Как я уже сказал, это не так уж и плохо, но было бы лучше, если бы они были более конкретными с именем, например, cloud-toolkit, или были бы разбиты на два отдельных репозитория / пакета, потому что, честно говоря, может существовать микросервис, который используют только одну из функций.
Да, в Django есть несколько пакетов utils. Позор им за использование названия utils. Однако обратите внимание, что, по крайней мере, некоторые из них могут быть отделены от фреймворка и они связаны как необязательные зависимости. Кроме того, по крайней мере, они сгруппированы в связные подпакеты — например, django.utils.timezone или django.utils.translation.
Если вы не пишете фреймворк, держитесь подальше от utils. 😉
Не совсем. В конце концов, может понадобиться пара вспомогательных функций. В этом случае организуйте такой код в модулях, названных по теме — например, datetime, phone_numbers и т. д. Такие функции должны быть чистыми (с точки зрения функционального программирования).
Чистые функции — не имеют дополнительного функционала, то есть они не меняют состояние программы. При одинаковых входных параметрах чистая функция всегда будет выдавать один и тот же результат.
https://stackabuse.com/functional-programming-in-python/
Не используйте utils как имя для вашего модуля Python и не помещайте его в имя класса. Постарайтесь более точно определить роль кода — например, validators, services или factories. Если критерий роли не помогают, и вы действительно имеете дело с утилитой, попробуйте сгруппировать код по его теме.
Модуль utils опасны, потому что со временем они создает беспорядок. Каждый, кто добавляет что-то, что никуда не подходит, с радостью добавит это в модуль utils, увеличив его несвязность. Беспорядок будет расти со временем, становясь все большим и большим бременем для работы.
Если вы видите недавно созданный модуль utils в ревью кода, запросите его переименование. Если у вас возникнет желание добавить что-то в существующие utils, создайте новое место для вашего кода и перенесите туда все из utils, которые соответствуют вновь созданному модулю.
В конце концов, вы будете тренировать свой мозг, чтобы стать лучше при разработке кода.
Краткий перевод: https://vuejs.org/guide/components/v-model.html Основное использование v-model используется для реализации двусторонней привязки в компоненте. Начиная с Vue…
Сегодня мы рады объявить о выпуске Vue 3.4 «🏀 Slam Dunk»! Этот выпуск включает в…
Vue.js — это универсальный и адаптируемый фреймворк. Благодаря своей отличительной архитектуре и системе реактивности Vue…
Недавно, у меня истек сертификат и пришлось заказывать новый и затем устанавливать на хостинг с…
Каким бы ни было ваше мнение о JavaScript, но всем известно, что работа с датами…
Все, кто следит за последними событиями в мире адаптивного дизайна, согласятся, что введение контейнерных запросов…
View Comments
А ты не думал писать буквы более связанно, чтобы получались слова, а затем предложения? Как попрактикуешься - напиши об этом статью
Что за бред я прочитал...