Moscow Python Meetup №86. Денис Аникин. Базовый кодовый стиль хорошего Python-бэкенда

Поделиться
HTML-код
  • Опубликовано: 27 сен 2024
  • Расскажу о том как эволюционировало представление о кодовом стиле у меня и у нашего внутрибанковского комьюнити и к чему мы пришли. Покажу свод правил, конфигурацию и опции настройки для того, чтобы относительно расслабленно систематически достигать очень хорошего качества исходного кода.
    Здесь не будет срыва покровов, взрывных правил, неожиданных утилит, крутых разработок, скорее собранное вместе руководство. Пригодится тем, кто не заморачивался на кодстайл; тем, кого не устраивает их кодстайл; тем, кого по какой-то причине не устроили существующие гайды.
    Слайды: speakerdeck.co...
    Moscow Python: moscowpython.ru
    Курсы Learn Python: learn.python.ru
    Moscow Python Podcast: podcast.python.ru
    Заявки на доклады: bit.ly/mp-speaker

Комментарии • 23

  • @StanislavM-j9x
    @StanislavM-j9x 10 месяцев назад +4

    Отличный доклад. Интересно, как внедрять ruff и mypy в старый проект. После прогона этими утилитами получаю 100500 ошибок, который править тяжко, в рамках не связанной доработки это безумие. А отдельную задачу на это не согласовать. Понятно, что в новых модулях прогонять код можно безболезненно, но часто приходится работать с функциональностью, которая уже содержит большое количество ошибок. Может есть рекомендации, как внедрять эти инструменты?

    • @a1d4rg
      @a1d4rg 10 месяцев назад +3

      Как вариант можно начать с малого и двигаться инкрементально. Для начала стоит добавить ruff и mypy как опциональные проверки исключительно для локального запуска. Все старые модули на начальном этапе закинуть в игнор, проверять только новый код. Затем можно по одному убирать модули из игнора и исправлять ошибки. Опишу подробнее инструкции для ruff и mypy по отдельности:
      В ruff убрать все категории правил (пустой select или ignore all). Затем можно по одному добавлять категории правил в ruff, попутно исправляя ошибки. Всё стоит делать отдельными небольшими коммитами. В случае если ошибок слишком много, можно заигнорить часть модулей/пакетов, которые содержат исключительно техническую логику (логгеры, мидлвари и т.п.). Не стоит с фанатизмом следовать всем правилам. Если не согласен с ошибкой - добавляй её в ignore. Рядом добавь комментарий почему правило было добавлено в исключение. Конечная цель внедрения ruff - select = ["ALL"] в конфиге и список исключений в ignore. В каких-то модулях, например тестах, можно выключить strict mode.
      Mypy настроить на наиболее щадящий режим проверки (без strict mode). Флаг --no-strict-optional может существенно сократить количество ошибок на начальном этапе. Как только ошибок не осталось - фиксируем правки и начинаем по-тихоньку закручивать гайки. Включаем strict флаги по одному, и исправляем ошибки. В модулях без бизнес логики можно пренебречь проверкой типов. Конечная цель - включенный strict mode и отсутствие ошибок у mypy. Для тестов и миграций можно добавить исключение и убрать strict mode.
      Конечно, всё это на словах звучит довольно просто. В реально на больших проектах на это могут уйти недели и даже месяцы. Главный совет - это двигаться маленькими шагами, а не перелопачивать весь проект разом, чтобы ревьюверы офигели с диффа на 10 тысяч строк.

    • @StanislavM-j9x
      @StanislavM-j9x 10 месяцев назад

      @@a1d4rg спасибо, звучит выполнимо, буду внедрять так

    • @alexred9963
      @alexred9963 7 месяцев назад

      @@StanislavM-j9x в видео показывали pyupgrade для обновления кода под новые версии. может он может помочь?

  • @Alex.M.
    @Alex.M. 10 месяцев назад +3

    Последние два ролика, звука нет. Как-будто не с микрофона писали, а на телефон у кого-то в зале.

    • @xfenix3
      @xfenix3 10 месяцев назад +1

      Со звуком правда как-то странно вышло :(

  • @funkindy
    @funkindy 10 месяцев назад +8

    Звук?)

    • @drevoborod8613
      @drevoborod8613 10 месяцев назад +1

      Ага, перегружен :(

    • @Flowmastaz
      @Flowmastaz 10 месяцев назад

      И видео в 720(

  • @xor2003
    @xor2003 6 месяцев назад

    исправить косноязычный текст помогает gpt

    • @xfenix3
      @xfenix3 6 месяцев назад +1

      А написать полный текст комментария не помогает, походу. Чтобы исправить что-то нужны конкретные примеры такого текста

  • @bunta8789
    @bunta8789 7 месяцев назад +1

    Звук и качество видео отвратительные

  • @TheTmntmike
    @TheTmntmike 10 месяцев назад +3

    Вся это самодокументированность очень быстро разбивается об жестокую реальность.

    • @xfenix3
      @xfenix3 10 месяцев назад +2

      Это документация как раз разбивается, ибо её никак написать правильно невозможно. А самодокументация у нас прекрасно работает. Я конечно не работаю с проектами по миллиону строк кода, но у нас уже вполне сотни тысяч и десятки сервисов. Полет прекрасный. Реальность у меня такая же жестокая как и у всех, собственно :)

    • @proofit404
      @proofit404 9 месяцев назад

      @@xfenix3 Когда это заложено в процессы а не отдано на откуп самодисциплине разработчиков - реальность не такая уж и жестокая.

    • @xfenix3
      @xfenix3 9 месяцев назад +2

      @@proofit404 вещи, которые ты можешь заложить в процессы обычно формулируются простыми правилами, и от этого чаще всего полезные артефакты не плодят. В моей практике, по крайней мере. И в практике многих коллег. Мы поэтому не плодим лишнего. Но, безусловно, людей, которые утверждают обратное, всегда хватает и у них на словах всегда всё хорошо. Я в этом смысле предлагаю честный путь, без тайных знаний и намеков, что у нас то все хорошо. Про реальность скорее игра слов. Вообще, думаю, тут в комментариях пускай каждый выберет какая у него она.

  • @НикитаДавыдов-д3ь
    @НикитаДавыдов-д3ь 8 месяцев назад +1

    >Вербозные названия всего
    >Не используйте слово get
    Одно другому противоречит
    Если делать вербозные названия, которые учитывают контекст, то слово get никому не помешает, будет всем понятным и никакой разницы не создаст
    Лучше бы упомянуть, что нужно всегда в нейминге учитывать контекст пространства имен, в котором мы придумываем название чему-либо -> название модуля/файла/класса/входных параметров метода или функции

    • @xfenix3
      @xfenix3 7 месяцев назад +1

      Как же противоречит? Вербозности в слове get нет, это общее ничего не значащее слово в контексте большинства программных продуктов. Мое личное наблюдение и мнение. И, чтобы это понять, можно встретить миллион гетов в той же джанге, которая лепит его к каждому второму методу. В итоге сводит смысл слова в ноль. Слово get значит что-то когда мы достаем что-то из оперативной памяти, а лепят его везде и всюду. Не видя границ и смысла, не зная других слов. Кажется в докладе я как раз про это и говорил.
      Следующий момент. Я когда создавал кодстайл для множества людей понял, что люди воспринимают только очень простые правила. Сложные с кучей «но» и «если» отбрасываются. В итоге слово get под мягким «запретом» в кодстайле у нас, вместо него предлагаются альтернативы. В итоге у нас почти и не встретишь get, только в контексте «получить из оперативной памяти». Почти все у нас это знают. Работает хорошо, код читать приятно.
      > Лучше бы упомянуть, что нужно всегда в нейминге учитывать контекст пространства имен, в котором мы придумываем название чему-либо -> название модуля/файла/класса/входных параметров метода или функции
      Не уловил твою идею. Если переформулируешь, можно будет обсудить. Если это то, о чём я подумал, то это мне не нравится из-за дублирования смыслов. Для неймспейсов у нас есть прекрасные правила импортов, которые закрывают потенциальный клеш имен.

  • @fedorok12345
    @fedorok12345 10 месяцев назад +2

    Ох, как много инструментов, надо как-то вникать

  • @deskentunhuman3336
    @deskentunhuman3336 10 месяцев назад +1

    Приведенный конфиг для isort сортирует вообще не так, как хотелось бы.

    • @xfenix3
      @xfenix3 10 месяцев назад

      Он точно сортирует так как описано в pep8, это мой рабочий конфиг, много лет с ним прогонял. Вопрос личных пожеланий остается открытым, я в докладе топлю, что эти хотели контр-продуктивны, на мой взгляд, но в вашем проекте никто не оставит вас от тотального изменения конфига isort, он как-то безумно совершенно конфигуруется.

    • @deskentunhuman3336
      @deskentunhuman3336 10 месяцев назад

      PEP8 говорит:
      Импорты должны быть сгруппированы в следующем порядке:
      - импорты из стандартной библиотеки
      - импорты сторонних библиотек
      - импорты модулей текущего проекта
      Вставляйте пустую строку между каждой группой импортов.
      В приведенном конфиге импорты идут в следующем порядке:
      sections = ["FUTURE", "STDLIB", "FIRSTPARTY", "THIRDPARTY", "LOCALFOLDER"]
      Что располагает импорты таким образом:
      - импорты из стандартной библиотеки
      - импорты модулей текущего проекта
      - импорты сторонних библиотек
      Таким образом верный порядок должен быть таким:
      sections = ["FUTURE", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"]
      Я сам удивился когда применил твой конфиг и получил не то, что говорит ПЕП8 )

    • @xfenix3
      @xfenix3 9 месяцев назад

      @@deskentunhuman3336 ага, ну понятно, да косяк на слайде, ты прав. Раньше я привожу нормальный пример. Вообще, в целом, я с этим конфигом неправ даже чуть больше, т.к. гонял с конфигом зря, дефолтный набор секций такой и есть (как ты написал и как у меня было в презе текстом ранее). Не знаю что меня переклинило. Самое главное no_lines_before, чтобы получился pep8