LINUX.ORG.RU

Посоветуйте хороших практик написания кода на python

 ,


2

6

Делаю свой проект на питоне и замечаю, что со временем он так разрастается, что уже становится тяжело ориентироваться в коде, хотя стараюсь делать аккуратно и модульно.

Посоветуйте хороших практик написания кода на питоне (т.е. языке с динамической типизацией) чтобы код оставался понятным со временем.

★★★★★

что со временем он так разрастается, что уже становится тяжело ориентироваться в коде

Это проблема любого кода, питон тут не причём.

Докстринги, код функции или метода не больше, чем на страницу, один файл - один класс. Модульность, выносить общие утилиты типа логгеров в отдельные проекты и т.п.

vvn_black ★★★★★ ()
Последнее исправление: vvn_black (всего исправлений: 3)

Посоветуйте хороших практик написания кода на питоне (т.е. языке с динамической типизацией)

  1. Делать тесты.
  2. Писать код так, чтобы легче было на него писать тесты. Например, отделять логику от GUI.
i-rinat ★★★★★ ()

Посоветуйте хороших практик написания кода на питоне (т.е. языке с динамической типизацией)

В конторе юзаем mypy со включенным disallow_untyped_defs, очень помогает.

anonymous ()

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

Deleted ()
Ответ на: комментарий от WitcherGeralt

Неа, просто лень было писать развёрнуто. Что в одном модуле - классы или функции должны быть логически связаны, и если мелкие, то можно и десяток, а «многострочных» лучше поменьше.

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

vvn_black ★★★★★ ()

со временем он так разрастается, что уже становится тяжело ориентироваться в коде

Признак того, что этап прототипа пройден и надо переписать на продакшен-язык.

hbee ★★★ ()

Тут в треде сказали про отравление жабкой, так вот, именно отравиться и нужно — или если конкретнее, можно посмотреть как это происходит в мирах больших проектов (в том числе на жабке, да) и сделать так же.

В том числе, например, юзать интерфейсы для отделения реализации от структуры кода, в питоне для этого есть прекрасный модуль `abc`.

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

Я бы сказал, что нужно подумать над индексацией проекта, над каким-нибудь единым принципом который будет помогать локализовывать место с конкретной логикой.

Посоветуйте хороших практик написания кода на питоне

Тут не обязательно искать именно на питоне — мы живём в одном мире, и его правила и законы едины для всего. Лучше смотреть именно в эту сторону, в сторону общих принципов, не завязывая мышления на одной из тысяч технологий.

oxo ()
Последнее исправление: oxo (всего исправлений: 1)
Ответ на: комментарий от hbee

Признак того, что этап прототипа пройден и надо переписать на продакшен-язык.

Обилие библиотек под python иногда приводит к тому, что их тянут в проект все подряд, а потом на другом языке аналог подобрать не получается...

anonymous ()
Ответ на: комментарий от kookoo

Вот тут пробовали питон на раст заменить. Не понравилось. В 2 раза быстрее, но возни в несколько раз больше и код не читается. Если напишешь аналог кода на хаскеле, то можно будет о чем-то говорить.

https://ngoldbaum.github.io/posts/python-vs-rust-nn/

anonymous ()

он так разрастается, что уже становится тяжело ориентироваться в коде, хотя стараюсь делать аккуратно и модульно

Значит не стараешься. Когда делают аккуратно и модульно, «ориентироваться в коде» вообще не нужно, потому что единицей изменения будет один модуль помещающийся на экран.

на питоне (т.е. языке с динамической типизацией)

Для начала, не использовать его как язык с динамической типизацией. Т.е. аннотации типов + mypy --strict.

slovazap ★★★★★ ()
Ответ на: комментарий от anonymous

этот смешной опус говорит не о питоне, а что раст не имеет ни оберток к ML-фреймворкам ни своего приличного.

и нафига для клея ML-моделей статический язык, если современные фреймворки могут сами компилировать модели, а размерности тензоров плохо типизируются. в общем задача не показательна

anonymous ()

хорошей практики на питоне вообще не может быть. Самое лучшее это Visual Basic. Там идеальный код. Как по написанию так и по чтению.

anonymous ()

Писать код под тесты и логи. Тесты вообще желательно писать перед кодом по возможности.

Код, который хорошо покрывается модульными тестами - автоматически получается модульным.

Если по тестам и логам не удаётся найти проблемы в коде, особоенно на чём то высокоуровневом - это тревожный звоночек. Тут либо недостаток бюджета, либо низкоквалифицированные разработчики.

Есть ещё один интересный нюанс - с течением времени, если индивид развивается, даже его собственные поделки начинают ему напоминать говнеццо.

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

Есть ещё один интересный нюанс - с течением времени, если индивид развивается, даже его собственные поделки начинают ему напоминать говнеццо.

Да, это норма. Если от своих старых поделок не тянет блевать, значит ты уже кончился как инженер. Я вот давно уже кончился.

bread ()

Чтоб не разрастался, ищи сторонние библиотеки или даже в батарейках и заменяй ими своими костыли. Например, используй logging вместо кастомых трейсов, очень гибкая и мощная штука. В батарейках вообще дохренища полезных кирпичиков, практически любая проблема, загугленная на stackoverflow приведёт тебя в стандартную библиотеку. Используй питонью функциональщину по максимуму (пока позволяет читабельность), многие циклы успешно сворачиваются в короткие однострочники. Используй декораторы. Используй contextmanager. Вообще углублённо изучать инструменты, с которыми работаешь - это для любых языков, естественно.

Оставшийся код разделяй на чистые/абстрактные классы/функции без побочных эффектов, которые оперируют только данными и легко покрываются тестами + постоянно прогоняются регрешн-тесты и проверяется покрытие. Используй моки (см. IoC).

Оставшиеся грязные огрызки с побочными эффектами (гуй, работа с файловой системой/сетью и т.п.) переписывай так, чтобы использовали твои чистые функции через IoC. Их должно оставаться совсем ничего, если их всё ещё много - там где-то вмешана логика, продолжай вырезать её в чистый код. Если в огрызках много данных (словари, наборы паттернов), их лучше отделить от кода или вообще вынести в отдельные файлы. Если паттернов очень много, возможно, проще использовать парсеры с грамматиками (я использую parsimoniuos, например).

Пиши комменты (материалов про то, как правильно комментировать код, в интернетах валом). Если можно комментов избежать с помощью читабельных названий функций/классов/переменных - лучше делай так, коммент должен описывать «как оно работает», а не «что это вообще такое». Любой интерфейс должен стремиться выглядеть естественно и быть ожидаемым, даже если ты не помнишь формальную сигнатуру функции. Стандартная библиотека - хороший пример.

Пиши документацию, генерируй документацию, индексируй документацию, ищи по документации. Если есть утилиты - пиши для них usage и документируй каждый аргумент. Сохранит много времени позже, когда будешь пытаться угадать, что делает каждый из них. Если предполагается использование другими людьми - собирай фидбек. Часто реальные сценарии, предложенные пользователями, заставляют переписывать и интерфейсы, и код более гибким и удобным способом. Бывает и наборот, конечно - тогда проблема у тебя в архитектуре, начинай цикл декомпозиции ещё раз.

Постоянно прогоняй через coverage, линтеры и любые другие чекеры (тот же MyPy), которые найдёшь. Большинство метрик и проверок сами по себе - фуфел, но в системе они могут помочь найти неочевидные ошибки.

В идеале любое изменение в коде должно быть покрыто тестами, чтобы ошибки ловились до реального использования путём нажатия одной кнопки. Если не используешь VCS, начинай и включай такие проверки в хуках.

Если модули большие (или вообще один файл), срочно разбей их на части. Желательно почитать мануалы по декомпозиции, если нет ООП бэкграунда, обратить внимание на связность/связанность - то, о чём писал vvn_black - это не только для ООП работает, но и для любых интерфейсов. Если модулей получилось много, не бойся делать иерархическую структуру.

Организуй этот набор модулей в пакет (setup.py, setup.cfg и прочее, гуглить по python packaging). Если модулей очень много и они мало связаны (см. связанность/связность), можно даже несколько пакетов сделать. Если это набор утилит, сделай entry_points, например, с помощью click. См. выше про usage и документацию скриптов. И лучше следовать Unix-way и организовывать скрипты так, чтобы их можно было естественно использовать в конвеерах.

E ★★★ ()