Жестко закодированные строковые значения, которые присутствуют в вашем проекте, негативно влияют на вашу способность к изменениям, но есть простой способ обойти это.
Но, во-первых, что не так с волшебными струнами?
Мы собираемся продемонстрировать использование статических классов для отслеживания констант в двух сценариях:
- Объявление маршрутов в приложении FastAPI
- Отслеживание метрик и артефактов в конвейере машинного обучения
Словари
Вам просто нужно передавать данные. Так заманчиво просто создать новый словарь и присвоить ему несколько элементов; Python делает это так просто, просто {a: b}.
Великолепно оптимизированный словарь Python является одновременно и благословением, и проклятием в плане удобочитаемости и удобства сопровождения кода. Неправильно иметь жестко запрограммированные константы. Переименование строки в одном файле может привести к проблемам в другой части программы. Если проект содержит хороший тестовый код, эта ошибка, вероятно, будет обнаружена во время тестирования. Если нет, то ваш API/конвейер данных/вы его называете взорвется в prod. Мы этого не хотим.
Предлагаемый метод: определения статических классов
Мы собираемся хранить все определения констант в одном месте: в модуле Python, внутри классов. Подобные иерархии могут помочь читателю/рецензенту понять объем ваших изменений, и есть довольно простой способ переименовать все, отредактировав несколько строк кода.
Давайте рассмотрим приложение FastAPI и продемонстрируем, как мы собираемся объявлять маршруты. Есть 2 способа обойти это. Выбрать свой яд:
- Относительная структура, в которой сам FastAPI отслеживает префиксы.
- И абсолютная структура, в которой классы отслеживают свою иерархию.
Лично я бы выбрал второе. Легче создавать URI, используя эти классы/лямбда-функции.
Давайте рассмотрим простой конвейер машинного обучения. Вы обучаете, оцениваете модель и отправляете метрики на какой-нибудь сервер отслеживания экспериментов. Почти все эти решения для отслеживания принимают очень специфическую структуру метрик, из-за чего так заманчиво использовать словари: str -> value
пары. Они также могут содержать некоторый индекс итерации или отметку времени.
Можно утверждать, что для каждого эксперимента вы можете объявить какой-то класс данных или типизированный словарь, чтобы отслеживать их. У вас может быть много необязательных частей, и реализация должна выглядеть так:
Вы видите, что все быстро становится загроможденным: необязательные поля со значениями по умолчанию None
и отсутствие представления с течением времени — вам нужно либо иметь список MetricsInstagram
, либо создавать новый класс данных, который содержит историю всех метрик для данного эксперимент. Проекты Data Science и Machine Learning неизбежно меняются очень быстро (особенно на ранних стадиях). Это выглядит как хорошее совпадение с полностью динамическими словарями.
Добавление нового варианта эксперимента или новой дополнительной метрики в конкретных случаях использования может замедлить весь проект только потому, что вам нужно поддерживать пакет метрик! Не говоря уже о том, что для этого необходимо получить все показатели с сервера отслеживания, сопоставить их с классом данных, а затем выбрать тот, который вам нужен!
Мы можем решить эти проблемы, используя (как вы уже догадались) статические структуры классов и области видимости! Вот что я имею в виду:
Это всего лишь демонстрация концепции. Я ожидаю, что заинтересованный читатель рефакторит и переставит части в соответствии со своими потребностями.
Это действительно гибкий подход, который поддерживает произвольные комбинации областей действия и названий метрик, а также учитывает определенную степень удобства сопровождения. На данный момент это мой личный выбор для проектов машинного обучения.
Спасибо за прочтение!