
Привет всем!
Как обычно это и бывает, я накопил критическую массу мыслей, и пора их как-то систематизировать, чтобы вы, мои замечательные читатели Хабра, могли что-то извлечь из моего опыта или поделиться своим :)
Я люблю и одновременно ненавижу статьи-обзоры в стиле «10 программ для {whatever}». Ненавижу — потому что их очень легко делать, вбил в гугл «программа для X», взял первые 10 ссылок, статья готова. Я называю такие статьи «лёгкий рейтинг». А люблю я их за то, что даже если 9 пунктов — чушь полная, то десятый, как правило, годный, я узнаю что-то новое, это что-то облегчает мне жизнь и позволяет мне быть более продуктивным.
Сегодня я побуду автором такой статьи — я расскажу вам про то, какие штуки я использую в разработке на питоне, если что-то из этого будет кому-то полезно — я буду рад. В своё время мне этого не хватало. А если вы знаете что-то круче — разнесите меня в комментариях.
Статья получилась ОГРОМНАЯ, и у меня был большой соблазн разбить её на сотню статей поменьше, чтобы в каждой ставить ссылки на свой телеграм-канал и получать гонорар за каждую по отдельности. Но я не буду. Пусть знания будут сгруппированы вместе. Welcome!
❯ Дисклеймеры
Во-первых, я не настолько глуп, чтобы утверждать, будто мой сетап единственно верный. Нет. Каждому своё, кому-то нравится минимализм, а кому-то — рубка космического корабля с тысячей кнопочек и лампочек.


Прелесть линукса и vscode в том, что вы можете собрать под себя тот инструмент, который вам нравится. На что я вас и пытаюсь сподвигнуть :)
Во-вторых, я топил и топлю за unix-философию, когда одна программа делает только что-то одно, и за счёт этого делает своё дело хорошо. Разумеется, на среды разработки такая философия ложится крайне посредственно, потому что мы в IDE и с git хотим работать, и тесты запускать, и много чего ещё. Мне это не нравится. Поэтому для всего, что не касается редактирования и изучения кода, у меня отдельные инструменты, и в данной статье за рамки этой философии я выходить не буду. Никаких rest-клиентов и просмотрщиков 3D моделек в IDE!

Ну, погнали!
❯ Рабочее окружение
Программирование начинается не с IDE, а с рабочего окружения в физическом мире. Я не буду тут обсуждать столы, стулья, марки ноутбуков итд — но расскажу о том, без чего не могу жить и что, имхо, хорошая инвестиция в себя любимого.
Подставка для ноутбука
Я считаю, что картинка лучше тысячи слов:

Подставка решает две проблемы:
Она освобождает приток воздуха под ноут, что важно, если там воздухозаборники. Мой, собака, греется как печка, и подставка хоть как-то помогает (но не сильно)
Подставка поднимает ноутбук, а вместе с ним и голову погромиста. Осанка всё равно так себе, но хотя бы не так плоха, как могла бы быть.
Стоимость минимальна по сравнению с приносимой пользой, а ещё эта вещь довольно компактно складывается и помещается в рюкзак. Комфортно ли рукам работать с «поднятым» ноутом? Внезапно, да.
Есть ещё младший брат — подставка под телефон. Идея та же — не нужно опускать голову, чтобы что-то посмотреть. При этом может иметь вырез для зарядки.
Шумоподавление
Часто я ухожу работать в библиотеку. Несмотря на обманчивое название, которое обещает мир и покой, время от времени там проводятся всякие бесовские обряды: русские народные пения, детские кружки с визгами и криками, дуэли в роблоксе на маломощных компах и ещё куча всего. Веселье полным ходом, в общем.
Но мне всё равно, ведь стоит мне включить шумоподавление — и все свистопляски исчезают. Порой я даже музыку не включаю и просто работаю в тишине. Поэтому шумоподавление— это хорошая инвестиция в своё психическое здоровье и улучшение концентрации.
Pomodoro
Я уже не в том возрасте, когда я готов работать за идею. Мне деньги подавай. Но иногда проект попадается настолько скучный, что меня просто тошнит от него, и ничто не может меня заставить работать — ничто, кроме pomodoro timer.
Если техника вам неизвестна, то вот суть: вы разбиваете ваш рабочий день на чанки по 25 минут, между ними перерывы 5 минут. Зачем? Концентрация:

Но для меня это не только про концентрацию. Pomodoro превращает скучный рабочий день в примерно десяток скучных рабочих промежутков, на зато каждый промежуток — это всего 30 минут. Мой мозг не понимает, зачем работать целый день, если можно не работать целый день, но заставить его поработать 30 минут и получить отдых — достаточно просто.
Во все самые тёмные времена меня спасал вот этот таймер для Android: Focusmeter. Без него ваш погромист не погромист.

❯ Софт
Так уж получилось, что я люблю мобильность, поэтому зачастую сижу за ноутом, а вместо мыши у меня тачпад. В таком сетапе экранного места мало, поэтому я экономлю на всём, и неиспользуемого пространства почти нет.
Linux
Я плотно сижу на Linux и переезжать не собираюсь. Потому что мне нравится страдать с драйверами nvidia все сервера как правило на линуксе, и мне удобно, когда везде одно и то же окружение и знакомые утилиты. Ну и кастомизация, да.
Конечно, на Windows совершенно точно существует разработка, но я её никогда не видел вживую. Один мой windows-товарищ на вопрос «а как ты кодишь python на windows?» ответил «а я уже переехал на Ubuntu», а второй сказал: «я загружаю Windows, открываю VirtualBox с Linux Mint и работаю».
Да, это субъективно, но и вся статья такая, сорри :)
XFCE
14 дюймов диктуют жёсткие условия. Поэтому я выбрал xfce4. Оно мне нравится по трём причинам:
Оно легковесное! Зачем мне прозрачные окна, всякие вылетающие в лицо свистоперделки, если я хочу просто работать / смотреть видео / читать текст / писать статью? Минимализм и лаконичность — это уже красиво само по себе.
Можно выпилить шапки окон! Вы никогда не задумывались, что они бесполезны? Для закрытия / сворачивания / разворачивания и вообще всего есть хоткеи, и получается быстрее, чем тащить мышкой. Заголовок окна мне не сдался вообще. Поэтому — никаких шапок и границ. В xfce для перетаскивания окон можно зажать alt и тащить окно за любую часть (а не только за заголовок) — так даже удобнее. Если вы решите повторить мой подвиг, то создавайте пустую тему (
touch ~/.themes/empty/xfwm4/themerc
), и в window manager выбирайте эту "empty" тему.

Внезапно, в xfce можно сделать вертикальную панель управления почти без всяких грязных хаков, и когда привыкаешь, то становится непонятно, зачем их делают горизонтальными! Они ж больше места занимают по вертикали, а его и так мало!
В общем, проще увидеть:


Tilda
Я постоянно зависаю в терминале, а зачастую у меня открыто сразу 4 окна со всякими докерами-шмокерами, django runserver
, django shell
, ssh
-сессиями итд. Чтобы не путаться с окошками, я юзаю Tilda — это терминал, который по нажатию на F1
(или любой другой хоткей) выезжает из ниоткуда и может потом так же уехать в никуда. Вот, смотрите:

На десктопе, где 2560px в ширину, настроил, чтобы tilda выезжала слева:

В tilda ещё прикольно вот что:
Можно открывать сколько угодно вкладок (
ctrl+T
), и перемещаться между ними по хоткею, как между вкладками в браузере. Закрываются вкладки тоже как в браузере (ctrl+W
).Можно конфигурировать прозрачность и высоту. По
F11
можно его развернуть на весь экран, но у меня он по умолчанию занимает половину экрана, потому что тогда я могу на одной половине экрана тыкать в браузер, а на другой видеть терминал и что там выводится, когда я тыкаю. Это бывает удобно.Можно настроить infinite scroll, чтобы не было лимита на количество строчек (ну как и в других терминалах, я полагаю). Не важно, сколько данных мне напечатает команда в терминал, ничего не пропадёт, потому что я могу отмотать в самое начало.
Работает поиск —
ctrl+shift+F
Главное, конечно — много терминалов на расстоянии одной клавиши, не занимают место на экране и не замусоривают список открытых программ.
Нужно больше шорткатов!
Экран маленький, ничего из UI нет. Поэтому назначим на всё горячие клавиши! Тем более это всегда быстрее, чем тыкать мышкой.
Долгое время кнопка «windows» у меня на клавиатуре простаивала (какой нафиг «Пуск» на linux!), но теперь она у меня — запускатор. Win+S открывает, например, Slack, Win+C — vscode, Win+T — окошко терминала, итд. Причём команда на шорткат примерно такая: sh
—c "wmctrl -a Slack || slack"
, что на русский переводится так:
Перенеси меня колечко
Через лесок, через крылечко,
В окошко, где мой Слак родной,
А если нет, тогда открой.
Все эти шорткаты позволяют почти не использовать alt-tab, потому что я сразу прыгаю в нужное мне приложение. Чего и вам желаю.

ULauncher
Всё, что не на хоткеях, запускается через GUI запускатор. Раньше я использовал Synapse, сейчас перешёл на Ulauncher, потому что он красивей и для него уже написаны (и можно написать свои) плагины на питоне, например, менеджер flatpak, AI-чат (ollama, chatgpt, ...), fuzzy поиск, системный монитор итд. Это ж бомба! Свои плагины пишутся за 3 секунды и ставятся прям из github.
Назначаете ентот лаунчер на удобную клавишу, и все программы на расстоянии нескольких нажатий клавиш.

Также есть встроенный калькулятор, выручал не раз:

Ещё есть классный плагин fzf (fuzzy find). Я ввожу z моя-упоротая-презентация
, и оно само ищет мою упоротую презентацию по всей файловой системе. То есть я могу открыть любой файл, не ища его в иерархии файловой системы. С папками тоже работает.
Это жутко удобно.
Ollama
Ну конечно, куда ж без LLM! На десктоп я прикупил себе 16Гб VRAM, чтобы хоть какая-то модель туда влезала. Вопреки распространённому мнению, что AMD не умеют в языковые модели — они умеют. И ollama — софт для скачивания и запуска моделей локально — тоже поддерживает карточки Radeon. Так что пофиг, за красных вы или зелёных — качайте ollama, и будет вам счастье.
Чего в этой ламе не хватает — так это нормального интерфейса. Поэтому рекомендую скачать open-webui, чтобы иметь что-то похожее на диалоговое окно chatGPT, с возможностью прикреплять картинки. Чтобы не засорять систему, запускать можно через докер, но я пошёл дальше и запускаю его как демона (переменная WEBUI_AUTH=0
— чтобы пароль не просил):
❯ cat /etc/systemd/system/open-webui.service
[Unit]
Description=Open WebUI Docker Container
After=ollama.service
Requires=ollama.service
StartLimitBurst=3
Restart=on-failure
RestartSec=10
[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/docker run --rm -p 3000:8080 --network=host -v open-webui:/app/backend/data -e OLLAMA_BASE_URL=http://127.0.0.1:11434 -e WEBUI_AUTH=0 ghcr.io/open-webui/open-webui:main
[Install]
WantedBy=multi-user.target
Теперь у нас свой chatgpt в браузере по адресу http://127.0.0.1:8080
WebUI / PWA
Многие приложения выставляют веб-морду, но часто хочется, чтобы было отдельное окно, как приложение. В браузере vivaldi можно любую страничку установить как отдельное приложение, если кликнуть правой кнопкой мыши на вкладке и нажать Install ...
. Поэтому open-webui, яндекс.музыка, syncthing и прочие веб-приложения у меня выглядят как нативные приложения, хотя по факту это просто веб-странички.

Flatpak
У нас, линуксоидов, есть репозитории, откуда мы ставим наш софт. Но иногда там может чего-то не быть!
Если софта нет в официальном репозитории дистрибутива, можно подключить сторонний репозиторий (например,
https://download.docker.com/linux/ubuntu
для докера)Можно посмотреть рецепт, как собрать из исходников самому (например, Arch User Repository)
Можно запустить через Docker
Можно превратить WebUI в приложение, как в предыдущем пункте
Но последний оплот — это Flatpak / AppImage / Snap, когда приложение целиком запаковано вместе со всеми необходимыми библиотеками. Очень выручает в случаях, 1) когда нужно проприетарное приложение, недоступное в репах (типа zoom), и 2) когда приложение не запускается из-за каких-то несовместимостей библиотек (типа zoom).

Из важного могу отметить мою ненависть к Snap, который авто-обновляется и который почему-то начинает заменять нативные приложения на Ubuntu. Фу!
Терминал
Как я уже сказал, я живу в терминале, и мне хорошо. Вот что мне помогает.
Лайфхаки в терминале
Многие это, наверно, знают, но когда я впервые об этом узнал, это перевернуло игру (с):
ctrl+A
перемещает курсор в начало строкиctrl+E
перемещает курсор в конец строкиopen .
откроет текущую папку в подходящей программеopen {file}
откроет файл в подходящей программе
С open
use-case достаточно частый — иногда я хочу какой-то GUI для работы с файлами — например, посмотреть превью фоток в папке. Терминал мне это не покажет, поэтому я делаю open .
, открывается файловый менеджер, и я всё красиво вижу. Могу написать open file.csv
, и вот файл открыт в офисной программе.
Fish
Раньше я мог настроить bash до вменяемого состояния. Или поставить zsh, накатать oh-my-zsh и дотюнить его по вкусу.
Но сейчас мне лень. Поэтому я ставлю fish shell, в котором из коробки:
подсветка синтаксиса
автодополнение (tab-completion)
нормальное перемещение по истории
синтаксис получше, чем у bash
Из минусов:
Он несовместим с синтаксисом bash, так что просто скопировать shell-инструкцию из этих ваших интернетов и запустить в fish не получится (но всегда можно
bash -c "скрипт из интернета"
). С другой стороны, с запуском bash-скриптов никаких проблем нет,bash
myscript.sh
будет работать как обычно, так что жить более-менее можно.Нет heredocs, и это бесит.
Настраивать строку ввода? Мне лень. Поэтому я ставлю starship, который может показывать кучу всего из коробки. Мне нравится, что если я нахожусь в папке проекта, то он покажет только название проекта, а не весь путь до него. Ну и текущую ветку git и версию питона.

Можно ещё поставить плагин fish-ai и получить AI в командной строке — либо сторонний (например, условно-бесплатный groq), либо локальный через ollama. Хотя мне не зашло — качество gemma3:12b
тут оставляет желать лучшего.
Zoxide
Zoxide — это замена команде cd
, с которой вы потом не слезете.
При установке появляется алиас z
, и теперь чтобы перейти в папку ~/some/very/very/long/path/to/work
, я пишу просто z work
. Так же как и в ULauncher, я не должен помнить, где именно находится папка, zoxide сам всё найдёт и просто переместит меня в нужное место, не важно, насколько глубоко в файловой системе оно находится.
По работе у меня штук 20 проектов, и я за одну команду могу прыгнуть в любой из них!

Direnv
Как я уже сказал, у меня два десятка проектов для клиентов, и ещё примерно столько же моих собственных пет-проектов. Для всех свои настройки — где-то нужно использовать один ssh ключ, где-то другой, в каждом своя версия питона, свои ключи к API, профили AWS и т.д. И тут мне помогает direnv.
Суть утилиты — она ищет в текущей папке файл .envrc
(и .env
, если настроить) и автоматически запускает его. Внутри файла вы можете что-то выполнять, но основной сценарий — задавать переменные окружения. Когда вы «выходите» из папки (то есть оказываетесь выше по иерархии), то все эти переменные окружения выгружаются. Зачем задавать переменные окружения? Потому что, согласно 12-factor app, конфигурацию приложения нужно хранить в переменных окружения.

Сценарий использования:
Я зашёл в папку проекта, и все переменные окружения заданы. Теперь я могу запустить, скажем, ./
manage.py
runserver
, и приложение успешно запустится, потому что оно берёт настройки из переменных окружения, а они уже автоматически заданы.
Тут есть один нюанс: .envrc
— это просто скрипт с экспортом настроек, выглядит вот так:
> cat .envrc
#!/bin/sh
export POSTGRES_DB=project
export POSTGRES_HOST=localhost
export POSTGRES_PORT=5432
export POSTGRES_USER=postgres
export POSTGRES_PASSWORD=12345
Но часто эти переменные окружения нужно передать ещё в docker compose, а он понимает только .env
файлы. .env
-файл — это не скрипт, а просто перечисление ключ=значение
:
> cat .env
POSTGRES_DB=project
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_USER=postgres
POSTGRES_PASSWORD=12345
Получается, что одни и те же настройки приходится задавать в двух местах:
в
.envrc
для автозагрузки черезdirenv
в
.env
для docker-compose и прочих программ, читающих env-файлы
Поэтому либо настраивайте direnv, чтобы он читал .env-файлы, либо внутри .envrc
запускайте dotenv
:
# .env
POSTGRES_DB=project
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_USER=postgres
POSTGRES_PASSWORD=12345
# .envrc
#!/bin/bash
dotenv # загружает всё из .env
Итого: при заходе в папку любого проекта у меня автоматически уже настроено окружение для работы с ним. Кайф.
Trash-cli
Когда я в стопятьсотый раз удалил что-то при помощи rm -rf
и пошёл гуглить, как восстановить файлы в ext4 (вкратце: жопа!), я задумал решить проблему раз и навсегда.
trash-cli
— это замена rm
, которая не удаляет файлы безвозвратно, а перекладывает их в корзину. Она совместима с интерфейсом rm
, поэтому я сделал просто alias rm="trash"
, и теперь rm -rf *
поместит всё в корзину, а не в небытие. Вот, например, я случайно удалил файл, а потом передумал и восстановил:
> rm project/core/migrations/0006_dayoff_commitment.py
> trash-restore project/core/migrations/0006_dayoff_commitment.py
0 2023-09-19 15:23:07 .../app/src/project/core/migrations/0006_dayoff_commitment.py
1 2023-09-19 16:04:44 .../app/src/project/core/migrations/0006_dayoff_commitment.py
2 2023-09-19 16:39:05 .../app/src/project/core/migrations/0006_dayoff_commitment.py
What file to restore [0..2]: 2
Сколько раз это спасало мою программистскую попу - не передать словами!
Разумеется, помимо удаления-восстановления утилита позволяет очищать корзину: trash-empty
.
Есть ещё rip.
Xh
xh
- это замена curl
/ wget
. Я использую эту утилиту, когда мне нужно прям быстро потестить какой-то запрос, например, отправить что-нибудь на локалхост при разработке. Синтаксис супер-простой:
xh POST --json "https://some-website/api/endpoint" \
title="Something" \
ApiKey:12345
Строчка выше отправит POST-запрос с content-type=application/json
на указанный endpoint, при этом тело запроса будет{"title": "Something"}
, а один из заголовков будет ApiKey=12345
. Это удобно.
xh help
выдаст полную справку по синтаксису. Поначалу непривычно, потом уже пишешь на автомате:
key==value
Add a query string to the URL.
key=value
Add a JSON property (--json) or form field (--form) to
the request body.
key:=value
Add a field with a literal JSON value to the request body.
Example: "numbers:=[1,2,3] enabled:=true"
key@filename
Upload a file (requires --form or --multipart).
To set the filename and mimetype, ";type=" and
";filename=" can be used respectively.
Example: "pfp@ra.jpg;type=image/jpeg;filename=profile.jpg"
@filename
Use a file as the request body.
header:value
Add a header, e.g. "user-agent:foobar"
header:
Unset a header, e.g. "connection:"
header;
Add a header with an empty value.
Для более основательных экспериментов, разумеется, рекомендую что-то с GUI:
Jq
jq
получает на вход сырой json, красиво форматирует и возвращает то, что вам оттуда нужно. Представьте, что вышеупомянутый xh
возвращает из API вот такое:
> xh https://...
{"activities":[{"id":3807068273,"date":"2022-10-01","message":"abc"},{"id":3807075992,"date":"2022-10-01","message":"cde"},{"id":3807083990,"date":"2022-10-01","message":"efg"}],"pagination":{"next_page_start_id":3807083991}}
Тогда применим jq
, чтобы получить, например, только id
и date
:
> xh https://... | jq ".activities | .[] | [.id, .date]"
[
3807068273,
"2022-10-01"
]
[
3807075992,
"2022-10-01"
]
[
3807083990,
"2022-10-01"
]
Даже если вам не нужно ничего из json доставать, то jq всё равно удобен в тех случаях, когда данные возвращаются в формате «json-каша» (это когда нет переносов строки и отступов). Jq выводит данные так, что их становится легко читать.
Glances
Есть top
, есть htop
, а есть мультиварка под названием glances
. Мне нравится, что там CPU, GPU, RAM, сенсоры и, конечно, процессы.

The Fuck
Я сам не пользуюсь, но кто-нибудь в комментах обязательно напишет, так что я иду на опережение! Встречайте: The Fuck. Исправляет опечатки по команде fuck
:

fzf
Fuzzy-поиск с утилитой fzf: можете вводить искомое как попало, и всё равно найдётся. Причём быстро!

Obsidian
Т.к. я привык работать в VScode, то мне хотелось вести заметки в нём. Но это неудобно по множеству причин, главная из которых — а как это перенести на мобильник?
И тут, конечно, выиграл Obsidian. Почему? Всё просто:
Obsidian похож на VScode: слева древо файлов, справа оглавление
Есть плагины
Есть шорткаты
Умеет рендерить markdown прям сразу во время редактирования
Есть версия для ПК и для Android, и они идентичны
Под капотом это просто .md файлы в папках, то есть никакой магии
Скриншот лучше тысячи слов (осторожно, рекурсия!):

Syncthing
Как-то в 2022 году оплата карточками накрылась медным тазом (спасибо, блин!), и облачный сервис Obsidian Sync перестал работать. А синхронизовать заметки между компом и телефоном как-то нужно!
К счастью, есть Syncthing. Этот софт — чистая магия. Ставите его на оба устройства, вводите настройки, оно само делает вжух-вжух, и файлы синхронизируются. Именно таким образом мои заметки всегда одинаковы и на мобильнике, и на ноуте, и на десктопе, и я за это ничего не плачу.
Взаимодействие идёт peer-to-peer, то есть синхронизация будет работать, только когда оба устройства в сети. Но такое у меня лично очень часто, поэтому я не замечаю лага. Если нужна абсолютная синхронизация, то поставьте ещё один инстанс syncthing на устройство, которое постоянно в сети — какой-нибудь дешёвый сервачок. Изи.

Можно пойти дальше и синхронизировать все заметки между своими устройствами, а какую-то подпапку — с другим человеком.
Минусы:
Синхронизирует любые типы файлов, поэтому каких-то специальных обработчиков для текста нет. Если в гите мы привыкли, что всё мерджится автоматически, то тут как только версии на устройствах не совпадают — появляются конфликт-файлы, которые нужно резолвить вручную. Есть решения, но нужно настраивать.
Иногда не синхронизирует какие-то файлы, и понять, какого хрена вообще — нет возможности. Бесит неимоверно. Возможно, я не умею его готовить.
Gitg
Ладно, тут наверно у каждого свои предпочтения насчёт просмотрщика VCS, и скорее всего, все юзают то, что встроено в IDE. Но лично я не очень люблю встроенные решения, в основном из-за паршивой визуализации. Да, я олдфаг, и я привык вводить git-команды в терминале, а не кликать мышкой. Поэтому всё, чего мне не хватало — хорошего просмотрщика истории git, вроде как git log --graph --oneline --all
, но всё же поприятнее. Потому что для понимания того, что, блин, нахрен происходит в этом богом проклятом репозитории, лучше всего подходит визуализация дерева коммитов.
Вот сравнение: GUI для Git: подборка популярных решений, там в комментах юзеры накидали ещё много всего. Но я как в том меме: что это фигня, что то фигня.
Мне просто нужна хорошая, понятная картинка, только и всего. Почему-то с этим лучше всех справился gitg. Смотрите сами: слева — diff для выбранного коммита, справа — дерево коммитов, где есть и local, и remote. Больше он ничего не умеет, а мне и не надо!

Он опенсорс, не нужна никакая регистрация, понимает любое git репо. Можно запустить из терминала прямо из папки с проектом: gitg . &
.
Meld
Иногда достаточно вызвать git diff
, чтобы посмотреть на текущие изменения. Но бывает, что хочется что-то подправить в этих изменениях, или увидеть «бОльшую» картину, и в этом случае помогает git difftool
, который показывает diff в сторонней программе.
У меня эта сторонняя программа — meld.
# настраиваем глобально один раз
git config --global diff.tool meld
git config --global merge.tool meld
git config --global --add difftool.prompt false
# запускаем
git difftool HEAD~5

В общем-то, подобные штуки встроены в IDE, но мне нравится, когда каждая программа делает только одну вещь. Meld отлично показывает diff'ы, и это всё, что мне от неё надо.
Если вам больше по душе , скажем, vscode, то можно указать его в git config diff.tool
выше — тоже будет работать.
Redshift
Как я жил без этого? Вечером и ночью монитор слепит синим цветом. Мне кажется, что уже на всех телефонах для этого сделали режим «защита зрения», когда экран начинает отдавать в желтизну.
В моём дистрибутиве принято страдать и настраивать всё самому, поэтому я поставил Redshift. Когда солнце садится, данная софтина делает цвет экрана более тёплым, и программировать становится гораздо приятней.
Мониторы, кстати, тоже позволяют настраивать цветовую температуру, так-то.
Screenshooter
Постоянно делаю скриншоты, в этом помогает xfce4-screenshooter, повесил его на клавишу PrntScr
. Он умеет фоткать нужную область или весь экран, с задержкой или нет, с последующим сохранением в файл или открытием в фоторедакторе. Дёшево и сердито.

ntfy.sh
В одном интернет-магазине у нас были уведомления в slack при поступлении нового заказа. А потом вжух — и slack закрыли для России. Тут на выручку и пришёл ntfy.sh — это сервис для нотификаций. Создаёте что-то вроде канала, отправляете туда что угодно через POST-запрос, и все подписанные на этот канал девайсы это уведомление получают. Есть клиенты для linux и android, можно смотреть через веб.
Код на питоне (6 строчек!):
def notify(message: str) -> None:
try:
response = requests.post("https://ntfy.sh/your-topic-name", data=message.encode('utf-8'), timeout=5)
response.raise_for_status()
except Exception:
log.exception('Could not send notification to %s', url)
Сценарии использования:
Уведомления: в вашем приложении что-то происходит, оно отправляет POST-запрос в ntfy.sh, все подписчики получают уведомление. Гораздо проще, чем настраивать телеграм-бота или, боже упаси, интеграцию со slack.
Тестирование xss: эксплуатируем уязвимость, украденные данные кидаем в ntfy.sh и анонимно их оттуда забираем :] Не нужен свой сервис, чтобы принимать данные.
Webhook на локалхосте: всякие сервисы любят присылать уведомления нам на вебхук. А как этот тестировать, если мы запустили приложение локально на 127.0.0.1:8000 и внешний сервис не пробьётся к нам через NAT? Можно использовать ngrok, чтобы получить временный внешний IP, но это нужно что-то настраивать и запускать у себя. Бюджетный вариант — сказать сервису, чтобы отправлял уведомления на ntfy.sh, а оттуда уже можно ручками или программно забрать данные и кинуть на локальный вебхук.
Кроме того, это оперсорс, так что если хотите приватность — без проблем, разворачивайте свой сервер. А ещё есть API, если хотите программно читать уведомления. Крутая штука!
Nox
Есть много всяких утилит для сборки, тестирования и запуска проектов. Самая популярная, наверно — это Makefile. К моему счастью, я дожил до момента, когда вовсю используются альтернативы. На слуху, конечно, всякие taskfile, just и tox, но у нас в компании как-то сложились тёплые отношения с nox.
Nox — это утилита для тестирования и сборки, где конфигурация делается через python-скрипт. Да, забавно: пакеты в питоне переезжают с setup.py
скриптов в императивный pyproject.toml
, а мы тут наоборот с yaml
и ini
перебираемся в формат скрипта. Почему? Потому что удобно!
Создаём noxfile.py
в корне проекта, пишем, какие команды что запускают:
import nox
@nox.session
def tests(session):
session.install('pytest')
session.run('pytest')
@nox.session
def lint(session):
session.install('flake8')
session.run('flake8', '--import-order-style', 'google')
... и по nox tests
запустится pytest.
Да, пример тривиальный. Нужно посложнее? У нас в репо есть такое: создаём новый проект из репозитория, инициализируем его, запускаем докер, потом запускаем тесты. После тестов всё подчищаем и выключаем. Такой вот монстр:
@contextlib.contextmanager
def docker_up(session):
session.run("docker-compose", "up", "-d")
yield
session.run("docker-compose", "down", "-v", "--remove-orphans")
@contextlib.contextmanager
def crufted_project(session):
session.run("pip", "install", "-e", ".")
tmpdir = crufted_project.tmpdir
if not tmpdir:
session.notify("cleanup_crufted_project")
crufted_project.tmpdir = tmpdir = tempfile.TemporaryDirectory(prefix="rt-crufted_")
session.log("Creating project in %s", tmpdir.name)
session.run("cruft", "create", ".", "--output-dir", tmpdir.name, "--no-input")
project_path = Path(tmpdir.name) / "project"
with session.chdir(project_path):
session.run("git", "init", external=True)
session.run("./setup-dev.sh", external=True)
else:
project_path = Path(tmpdir.name) / "project"
with session.chdir(project_path):
yield project_path
@nox.session(python=PYTHON_DEFAULT_VERSION, tags=["crufted_project"])
def test_crufted_project(session):
with crufted_project(session):
with docker_up(session):
session.run("nox", "-s", "test")
uv и uvx
Если вы разрабатываете на питоне и ещё не используете uv — то самое время переходить. Разрешает зависимости, делает локфайл, сам ставит нужную версию питона! Pyenv
, pdm
, poetry
и уж тем более pip
уходят в прошлое.
Но главная фишка, от которой я тащусь — это запуск утилит на питоне. Представьте, что есть какая-нибудь полезная программа, написанная на питоне. Куда её ставить и как запускать?
Либо ставить в userspace, засоряя
~/.local/lib/python3.x/site-packages/
Либо создавать ручками виртуальное окружение и ставить в него
К счастью, uv tool
(или, сокращённо, uvx
) сделает это всё за вас!
uvx command
скачает всё необходимое и запустит команду - например,uvx ruff@0.6.0
запустит ruff. Все наобходимые зависимости будут установлены во временную директорию.uv tool install
установит пакет перманентно (чтобы узнать, куда именно, наберитеuv tool dir
- у меня это~/.local/share/uv/tools
).
Почитать подробнее можно тут.
Я так запускаю nox
как раз:
uv tool install nox
uvx nox -s test
uncurl
Ещё одна из утилит, которую я запускаю через uvx
— это uncurl. Когда я анализирую, какие запросы делает сайт, я очень часто хочу их повторить в питоне. Для это в chrome dev tools я копирую запрос как curl и вызываю uvx uncurl
— утилита сама считывет запрос из буфера и превращает в питон-код:

❯ uvx uncurl
requests.post("https://habr.com/kek/v2/users/kesn/note",
data='hl=ru; fl=ru; theme=light; visited_articles=907904:840200:901368:892190:903376:903338:340146:901382:310460:438796',
headers={
"accept": "application/json, text/plain, */*",
"accept-language": "en-US,en;q=0.9",
"priority": "u=1, i",
...
},
cookies={},
auth=(),
proxies={},
)
Поставить можно прям из гита (но не забывайте читать исходники, когда так делаете):
uv tool install https://github.com/spulec/uncurl.git
Скрипты
Как, наверно, и у многих, у меня есть коллекция скриптов на bash, которые немного упрощают жизнь. Ничего необычного, но я хотел выделить парочку, без которых тяжко.
Бэкапы
Есть разные типы бэкапов — например, копирование в облако, снэпшоты ФС, — но мне нравится иметь «холодное хранилище», то есть отдельный жёсткий диск, на который я периодически копирую данные, в остальное время он пылится в ящике вдали от ноутбука. Мне нравится такой подход по двум причинам:
Физическое разделение данных. Даже если девайс сгорит или потеряется, данные будут доступны
Доступность. Это не облачный провайдер, для которого нужна сеть — тут всё буквально «в руках».
Контроль. Диск — оффлайн, никакого автоматического копирования нет. То есть не будет такого, что ОС обновилась, сделала бэкап, а потом оказалось, что она после обновления не загружается. Или утилита поставилась, снесла
/home
и записала это в бэкап. Нет, всё чётко под контролем. Я сам порчу свои данные.
Да, я сходу придумал несколько сценариев, когда эта схема с треском провалится, но тут уж каждый решает сам, насколько он хочет заморочиться.
Сам бэкап-скрипт супер-примитивен: это простой rsync
с несколькими специфическими флагами:
rsync -aAXHv --exclude-from="exclude.txt" --delete --delete-excluded / "$1"
В деталях всё описано на Arch Wiki: Rsync - full system backup.
Для копирования в облако есть неплохой Rclone
Cleanupz
Добавлять мусор в систему — легко, вычищать — сложно. Для этих целей у меня есть скрипт-уборщик, в последний раз он собрал около двухсот Гб мусора, чему я был несказанно рад. Команды простые, в основном это удаление ненужного докер-барахла:
#!/bin/sh -eux
paccache -ruk1 # чистим кэш пакетного менеджера, для Ubuntu подойдёт apt-get clean
journalctl --vacuum-size=500M # оставим только 500Mb логов journald
docker volume prune # удаляем все volume, не связанные с контейнерами
docker image prune -a # удаляем все image, не связанные с контейнерами
docker buildx prune # удаляем кэш buildx
docker container prune --filter "until=2160h" # удаляем остановленные более 90 дней назад контейнеры
docker images | grep "" | awk '{print $3}' | xargs docker rmi -f # удаляем "висячие" image
Cookiecutter
У нас в компании разработка на заказ, поэтому клиентов много. Каждый раз начинать строить проект заново — затратно, поэтому у нас есть шаблон проекта и набор опций (например, использовать celery
или нет). Когда нужно начать новый проект — мы отвечаем на несколько вопросов в терминале, и у нас из шаблона материализуется новый проект. Всё это делается при помощи Cookiecutter:
uv tool install cookiecutter
uvx cookiecutter https://github.com/reef-technologies/cookiecutter-rt-django
Все ответы на вопросы, которые вы дали перед созданием проекта, можно использовать где угодно — например, в коде. При создании проекта всё подсчитается и подставится.
import os
{% if cookiecutter.use_channels == "y" %}
from channels.routing import ProtocolTypeRouter, URLRouter
{% endif %}
from django.core.asgi import get_asgi_application
# init django before importing urls
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{cookiecutter.django_project_name}}.settings")
http_app = get_asgi_application()
{% if cookiecutter.use_channels == "y" %}
from .urls import ws_urlpatterns # noqa
{% endif %}
{% if cookiecutter.use_channels == "y" %}
application = ProtocolTypeRouter(
{
"http": http_app,
"websocket": URLRouter(ws_urlpatterns),
}
)
{% else %}
application = http_app
{% endif %}
Создавать файл или нет
Можно назвать файл {% if cookiecutter.some_condition == 'y' %}
main.py
{% endif %}
, и если у нас условие не выполнится, то файл main.py
вообще не будет создан.
Включаем тримминг
Очень рекомендую для cookiecutter настроить lstrip_blocks
и trim_blocks
, чтобы всякие {% if cookiecutter.some_condition %}
удалялись вместе со всей строкой, иначе после создания проекта будет очень много бесячих пустых строк.
Обновления
Ну хорошо, создали мы 10 проектов. А через месяц мы фиксим какой-то общий баг и хотим обновить сразу все проекты. Cookiecutter в этом никак не поможет, зато на выручку приходит Cruft. Он, как и cookiecutter, может создавать новые проекты по шаблону, но что важнее — он умеет обновлять существующие проекты при изменениях в шаблоне.
uv tool install cruft
uvx cruft create https://github.com/reef-technologies/cookiecutter-rt-django
# ... через месяц
uvx cruft update
Последняя команда применит изменения к вашему проекту, а если не сможет это сделать автоматически — то создаст миллион файлов-конфликтов *.rej
, которые вам нужно будет разрешить самостоятельно. Да, это ручная операция, не самый приятный процесс, но зато вы точно держите все изменения под контролем.
❯ VScode + python
Так уж получилось, что я на vscode. Это сложилось исторически, когда pycharm тормозил при прокрутке и выглядел как кабина самолёта, с миллиардом кнопок и переключателей. Сейчас всё, конечно, не так, и всем, кто меня спрашивает, какую IDE использовать для питона, я говорю: Pycharm. Она быстрая, там всё удобно из коробки, есть какие-то экзотические фичи типа удалённой отладки.
Вообще мы как-то попробовали на работе устроить холивар на эту тему, и вывод простой: если сравнивать пофичечно, то pycharm и vscode идут бок о бок, только в последнем нужно для всего ставить плагины. Поэтому pycharm выигрывает — там ничего делать почти не надо. С другой стороны, pycharm как бы для питона, а vscode — для всего. Короче, не знаю. На вкус и цвет.
Если вы, как и я, сидите на vscode, то вот какие фичи и плагины я считаю годными.
Внешний вид и ориентация в коде
Темки
Вкусовщина, но вдруг вам зайдёт.
Когда у меня подгорает — я включаю холодную Nord
Когда достаточно охладился — то горячую Flare
В остальных случаях — северо-сиятельную Ariake Dark
Так и прыгаю туда-сюда.
А вообще есть классный сайт для выбора тем: https://vscodethemes.com. Рекомендую.
Activity bar
Когда я начал всю эту тему с освобождением пространства на экране, я подумал и понял, что Activity Bar — вот эта панель слева, где Explorer
, Search
, Source control
итд — она не нужна. Две самые используемые вкладки — поиск и древо файлов — доступны по хоткеям (Ctrl+Shift+F
и Ctrl+Shift+E
соответственно). Поэтому я уменьшил Activity Bar и почти не вспоминаю про неё:
"workbench.activityBar.location": "top"

Secondary Sidebar
С другой стороны, почему-то Vscode не показывает secondary sidebar справа по умолчанию, а она очень удобна! Туда можно поместить что-нибудь, что вам дорого. Я, например, держу там «outline» — логическую структуру файла, т.е. список классов, методов и функций.
Открывается она по Ctrl+Alt+B
, но можно настроить, чтобы она была открыта по умолчанию:
"workbench.secondarySideBar.defaultVisibility": "visible"
Далее эту панель «outline» нужно ручками перенести из Primary Sidebar в Secondary Sidebar (слева направо).

Ещё нюанс: по умолчанию там показано всё, в т.ч. переменные — и получается каша. Я переменные оттуда убираю, и становится как надо:
"outline.showVariables": false,
Ну и напоследок: когда курсор находится внутри метода, то хочется, чтобы он подсвечивался в Outline (как на картинке ниже). Для этого нажимаем на «...» и жмём «Follow cursor». Увы, настройками это не сделать, и приходится каждый раз вручную активировать.

Визуализация проекта
Очень часто хочется увидеть весь проект «с высоты птичьего полёта», и я имею в виду не разглядывание дерева файлов в боковой панели, а что-то более глобальное.
Во-первых, можно визуализировать репо, как, например, сделано в Github Next: repo visualization. Вбиваете публичный репо — он вам строит кружочки. Вот cpython:

Есть ещё всякие плагины для IDE: Swark, Vxplain, CodeViz. Они пытаются использовать AI, чтобы нарисовать логическую структуру проекта. Работают все по-разному, чего-то прям выдающегося я не нашёл, но считаю, что так-то задумка хорошая.



Визуализация кода
Когда мне кажется, что я слишком умный и могу всё понять, я открываю вот этот кусок кода, который в своё время поломал мне мозг. Он ломает и сейчас.
class BucketListBase(Command):
@classmethod
def _setup_parser(cls, parser):
parser.add_argument('--json', action='store_true')
super()._setup_parser(parser)
def _run(self, args):
return self.__class__.run_list_buckets(self, json_=args.json)
@classmethod
def run_list_buckets(cls, command: Command, *, json_: bool) -> int:
buckets = command.api.list_buckets()
if json_:
command._print_json(list(buckets))
return 0
for b in buckets:
command._print(f'{b.id_} {b.type_:<10} {b.name}')
return 0
Тут вот есть метод run
, который вызывает классметод runlist_buckets
и передаёт туда свой инстанс и заодно команду типа Command
(хотя инстанс уже и так унаследован от Command
), а внутри этой команды вызывается метод какого-то API. Изи! Но вообще-то я ни черта не понял.
Для vscode есть всякие плагины для построения графа вызовов (call graph), например, Chartographer, Vxplain call graph, Source code visualizer итд итп. Но работают они посредственно, а почему — и так понятно:
def func_factory(param):
if param < .5:
return func_a
else:
return func_b
func = func_factory(some_variable)
func()
Что тут вызовется? А хрен его знает, без рантайма и не скажешь! Вот и автоматические тулзы совершенно не справляются с динамичными частями питона, и на примере с BucketListBase
получается чёрт-те что — оно вроде и показывает что-то, но про API умалчивает.

А что делать? Вариант 1 — спросить LLM (например, Copilot), что происходит. Вариант 2 —вручную пройтись по коду и посмотреть, что происходит. Но в переусложнённом коде слишком много ветвлений и наследования, и удержать всё в голове нереально. Поэтому особая почесть тем плагинам, которые позволяют раскидать код на плоскости вручную.
Сравните Source code visualizer в автоматическом режиме:

И он же, но код раскидан вручную:

Видите? Я как будто прикрепляю заметки с кусками кода, как в том меме. И всё становится понятно. Ну кайф же!

Закладки
Каждый день я читаю километры плохого кода, а плохой он в том числе потому, что запутанный. Распутывать код, помечать какие-то места, чтобы к ним вернуться, мне помогают закладки — Bookmarks.
По ctrl+alt+K
я отмечаю интересную строчку (например, я нашёл баг и хочу вернуться к нему позднее, или хочу отметить какой-то момент в цепочке вызовов). Все закладки появляются в панели слева, но ещё по ним можно прыгать хоткеями. Смотрю код, вижу — развилка: либо вглубь, либо вбок. Поставил закладку, пошёл вглубь стека вызовов, потом по хоткею вернулся к развилке и пошёл вбок.

Выделяем важные места
Во-первых, есть Better comments, который выделит особые комментарии, например, TODO
:

Но мне ещё нравится Highlight — он не только подсвечивает наперёд заданные комментарии, но я позволяет создавать свои правила вида «регулярное выражение -> цвет». Можете выделять красным цветом антипаттерны, например, или # UGLY
, чтобы было максимально ugly:

Выбираем глубину
Все знают, что есть folding — это когда кусок кода можно «свернуть» в одну строчку, чтобы он не мешал. Получается, что мы видим код «на поверхности», не ныряя в более глубокие участки кода.
Для автоматизации этого есть Fold level. После установки появляется такая панель в статус баре:

Нажимая, например, на «3», мы фолдим всё, что глубже уровня 3. Сравните это

и это:

Получается, мы можем просматривать код поверхностно, а можем погружаться на нужную глубину. Удобно не только в коде, но и при анализе больших json
, где с первого взгляда теряешься и неплохо было бы сначала хотя бы понять, какие ключи есть на верхнем уровне. Этот плагин здорово в этом помогает.
Отступы
В тему: иногда попадается отвратительная портянка из данных. Indent nested dictionary добавляет команду «отформатируй это непотребство». Работает на json и питоновских словарях, даже если они покорёжены и содержат синтаксические ошибки.
Было (заметьте: обрезано в конце):

Стало:

Оптимизация ввода и улучшение кода
Ладно, в коде мы ориентируемся, но нам бы ещё хотелось быстрее этот код писать и перемещаться по нему.
Хоткеи
Тут на самом деле совет один: выучите уже хоткеи. Я столько раз видел, как разработчик тыкал мышкой по дереву файлов в попытке отыскать тот самый, нужный, когда можно просто нажать ctrl+P
и ввести имя искомого файла!
На сайте vscode есть официальные шпаргалки по горячим клавишам для всех ОС. Скачайте и запомните, если ещё это не сделали — ускоритесь в разы.

LLM
Ну да, LLM всё-таки ускоряют ввод. Скажу честно: до недавнего времени LLM меня замедляли всегда, кроме случаев написания тестов и какого-нибудь жёсткого тупого копипастинга.
Но когда у Copilot появилась фича Next edit suggestions, наконец-то как будто мне стали предлагать то, что я хочу: не дополнение строчки, а автоматически изменить то, что я планирую изменить. То есть делаю рефакторинг и переименовываю какую-то вещь — copilot предлагает мне переименовать её и в других местах.

Ещё он умеет исправлять ошибки: если написать код с багом, то, по версии copilot, следующее логическое изменение — это баг исправить. Ну круто же!
Я тут нахваливаю copilot, но ещё же есть всякие windsurf'ы, continue, cursor'ы итд итп. Честно — я не в теме, и это потянет на отдельную статью. Но что мне нравится в copilot — там постоянно какая-то движуха идёт, плагин развивают, фичи появляются, и в нём есть бесплатный тариф. Как работается с другими AI-компаньонами и IDE — я не знаю, напишите, у кого какой опыт.
Ruff
Для линтинга и проверки на популярные ошибки крайне рекомендую использовать ruff. Да все его, наверно, уже используют — но вдруг нет?
Важно помнить, что по умолчанию в ruff активирован только минимум правил:
[lint]
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or McCabe complexity (`C901`) by default.
select = ["E4", "E7", "E9", "F"]
Хотите хардкорного линтинга — включайте все правила и страдайте: ruff check --select ALL
.
Ty
Не скажу, что досконально проверял эту утилиту, но тот факт, что создатели мегапопулярных ruff
и uv
пилят статический анализатор, о многом говорит. Должна получиться пушка! Пробуйте — uvx ty check
. А есть и в виде плагина для vscode.
Error lens
Я не знаю, кому удобно, когда ошибки спрятаны где-то на нижней панели. У меня они показываются прямо на экране: Error lens. Это здорово, потому что позволяет сразу видеть, где что-то пошло не так:

Есть одна проблема: когда я открываю какой-то чужой проект, обычно горит ВСЁ! Но это нормально.

Если вам всё же хочется применять ruff
только к новому коду, то вам в этот issue.
Отладка
Структурированные логи
Отладка, конечно, связана с логами. Но почему-то я редко вижу на проектах что-то отличное от import logging
. А зря!
Обычные логи — это мешанина текста, и все её пишут как им нравится. Структурированные логи вносят порядок: сообщение говорит о том, какое событие произошло, а атрибуты рассказывают нам о контексте этого события. На примере:
from logging import getLogger
log = getLogger(__name__)
def handle_request(request):
log.debug('Received request #%s', request.id)
if not request.user.is_authenticated:
log.debug('User %s is not authenticated, redirecting to auth page (request #%s)', request.user, request.id)
return HttpResponseRedirect(...)
...
Тут мы должны использовать ленивое форматирование ('%s', value
), повторять request.id
в двух строчках (и вообще во всех для этой функции), и важно не перепутать порядок аргументов. Сравним со структурированными логами:
from structlog import getLogger
log = getLogger(__name__)
def handle_request(request)
with bound_contextvars(request_id=request.id, user=request.user):
log.debug('request received')
if not request.user.is_authenticated:
log.debug('redirecting anonymous user')
return HttpResponseRedirect(...)
...
Во все логи будут автоматически добавлены request_id
и user
, при этом всё будет красиво выводиться на экран, и можно выводить не только как текст, но и, скажем, в формате json для дальнейшего автоматического анализа.
Есть разные библиотеки, например, loguru. Но я использую библиотеку structlog, потому что у loguru на логотипе заросший мужик, а у structlog — бобёр. Выбор как бы очевиден.
ipython
В интерпретируемых языках прикольно то, что можно запустить REPL, то есть интерактивную среду, где можно писать код и сразу видеть, как он не работает. В питоне туда можно попасть, если просто запустить python
. Но все знают: там некрасиво. Ведь REPL — это не только про запуск команд — это про вставку из буфера, написание многострочного кода, удобное автодополнение, раскрашивание синтаксиса и красивый вывод результатов. Всего этого нет в python
, но есть в ipython. Там даже ls
работает!

ipdb
Как здорово, если бы всю эту красоту из ipython
можно было притащить в отладчик... А вот можно! Для этого есть ipdb.
В коде вставляем import ipdb; ipdb.set_trace()
, и когда выполнение достигнет этой строчки, мы «провалимся» в ipython
. Если лень всё время писать ipdb.set_trace()
, можно задать переменную окружения PYTHONBREAKPOINT="ipdb.set_trace"
и в коде просто писать breakpoint()
:
print('Before')
breakpoint()
print('After')
Можно настроить pytest, чтобы запускал ipdb
при исключениях:
pytest --pdb --pdbcls=IPython.terminal.debugger:Pdb -v ./test_example.py
Понимаю, что сейчас те, кто пользуется встроенным в IDE отладчиком, начнут накидывать мне. Справедливо! Но иногде мне проще поставить breakpoint()
на нужную строчку и быстро посмотреть, что там происходит, чем настраивать отладочную сессию.
Кроме того, мне нравится, что в ipython можно отладить любую функцию «на месте»: даже если не установлены брейкпоинты, я могу вызвать %debug foo(1, 2)
и провалюсь в отладку этой функции с этими аргументами. Что-то вроде pdb.runcall()
.
Отладка в IDE
Зато в IDE отлаживать классно, потому что удобно — и все локальные переменные видно, и код как на ладони. Но я никогда не любил запуск отладчика в IDE, потому что там надо что-то настраивать — всякие launch.json
, в которых прописывать, что и как вызывать. Мне в принципе не лень это сделать один раз, но если я постоянно запускаю разный код разными командами и с разными аргументами, то каждый раз редактировать конфигурацию запуска мне вообще не прикольно.
Но внезапно я узнал, что можно запускать код как обычно, в терминале, а vscode подключать к этому коду в режиме отладки. Смотрите, так мы запускаем скрипт в режиме отладки, и он будет ждать, пока к нему подключится vscode:
python -m debugpy --listen 5678 --wait-for-client ./myscript.py
На стороне vscode я создаю такую конфигурацию один раз в жизни:
{
"name": "Python Debugger: Attach",
"type": "debugpy",
"request": "attach",
"connect": {
"host": "localhost",
"port": 5678
}
}
И всё, я запускаю эту конфигурацию в vscode и отлаживаю прям из IDE.
Бонус — можно заменить localhost
на что-то другое и отлаживать удалённо!
Logpoints
Я как-то пропустил этот момент и привык делать log.debug()
везде, где отлаживаю. А, оказывается, есть logpoints — возможность печатать что-то во время отладки, не засоряя код. Смотрите, при достижении строчки 2 будет напечатано сообщение, хотя никакого кода там нет.

Breakpoints
Помимо обычных брейкпоинтов есть conditional breakpoints, которые прервут выполнение только при достижении какого-то условия. Но если этого вам мало, то есть triggered breakpoints, которые «выполнятся» только если «выполнился» какой-то другой брейкпоинт.

Извините :] Но это мой родимый канальчик, я стараюсь, блин, чтобы было интересно и даже полезно, так что мне не стыдно. Поэтому...
Подписывайтесь на мой канал «Блог погромиста», если вам нравятся мои тексты и не хочется пропустить новые. А ещё есть мой сайт, где собраны все мои статьи, заметки, биография, CV, пароли, анализы, девичья фамилия матери, кличка первого питомца и ключи от холодного кошелька: pogrom.dev
Отдельная благодарность — облачному провайдеру Timeweb, у которых я держу свои проекты. Дёшево и удобно.
Новости, обзоры продуктов и конкурсы от команды Timeweb.Cloud — в нашем Telegram-канале ↩

Перед оплатой в разделе «Бонусы и промокоды» в панели управления активируйте промокод и получите кэшбэк на баланс.
SeveR31
Интересный сетап, правда местами кажется оверинжиниринговым. Хотя если системой пользоваться не только для работы, то должно быть самое то. У самого похожий, особенно в плане VsCode. Только один вопрос - а чего вместо терминала zsh не взять? Фичи с закладками и множеством окон почти везде есть, а там ещё ворох плагинов на любой случай жизни (даже можно сразу из консоли гуглить/фаерфоксить, было бы желание).
kesn Автор
Дефолтный fish покрывает все мои хотелки к терминалу и ставится одной командой, только и всего. Ничего против zsh не имею :)
Rafaell0
Это не оверинжиниринг, это базовая конфигурация. Автор деликатно умолчал о том, что каждый из этих софтов можно до двух суток подряд под себя настраивать, вот это уже будет действительно оверинжиниринг. Но он будет того стоить. В особенности подобрать плагины для UIlauncher или написать какой-нибудь поисковик по базам данных который будет выдавать до 10 строк в поисковом окне по ключевому слову "db" ...