Жестко закодированные строковые значения, которые присутствуют в вашем проекте, негативно влияют на вашу способность к изменениям, но есть простой способ обойти это.

Но, во-первых, что не так с волшебными струнами?

Мы собираемся продемонстрировать использование статических классов для отслеживания констант в двух сценариях:

  • Объявление маршрутов в приложении FastAPI
  • Отслеживание метрик и артефактов в конвейере машинного обучения

Словари

Вам просто нужно передавать данные. Так заманчиво просто создать новый словарь и присвоить ему несколько элементов; Python делает это так просто, просто {a: b}.

Великолепно оптимизированный словарь Python является одновременно и благословением, и проклятием в плане удобочитаемости и удобства сопровождения кода. Неправильно иметь жестко запрограммированные константы. Переименование строки в одном файле может привести к проблемам в другой части программы. Если проект содержит хороший тестовый код, эта ошибка, вероятно, будет обнаружена во время тестирования. Если нет, то ваш API/конвейер данных/вы его называете взорвется в prod. Мы этого не хотим.

Предлагаемый метод: определения статических классов

Мы собираемся хранить все определения констант в одном месте: в модуле Python, внутри классов. Подобные иерархии могут помочь читателю/рецензенту понять объем ваших изменений, и есть довольно простой способ переименовать все, отредактировав несколько строк кода.

Давайте рассмотрим приложение FastAPI и продемонстрируем, как мы собираемся объявлять маршруты. Есть 2 способа обойти это. Выбрать свой яд:

  • Относительная структура, в которой сам FastAPI отслеживает префиксы.
  • И абсолютная структура, в которой классы отслеживают свою иерархию.

Лично я бы выбрал второе. Легче создавать URI, используя эти классы/лямбда-функции.

Давайте рассмотрим простой конвейер машинного обучения. Вы обучаете, оцениваете модель и отправляете метрики на какой-нибудь сервер отслеживания экспериментов. Почти все эти решения для отслеживания принимают очень специфическую структуру метрик, из-за чего так заманчиво использовать словари: str -> value пары. Они также могут содержать некоторый индекс итерации или отметку времени.

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

Вы видите, что все быстро становится загроможденным: необязательные поля со значениями по умолчанию None и отсутствие представления с течением времени — вам нужно либо иметь список MetricsInstagram, либо создавать новый класс данных, который содержит историю всех метрик для данного эксперимент. Проекты Data Science и Machine Learning неизбежно меняются очень быстро (особенно на ранних стадиях). Это выглядит как хорошее совпадение с полностью динамическими словарями.

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

Мы можем решить эти проблемы, используя (как вы уже догадались) статические структуры классов и области видимости! Вот что я имею в виду:

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

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

Спасибо за прочтение!