Предположим что вы работаете с каким либо классом, в котором к примеру ~3000 строчек. Количество "принтов" увеличивается, и понять с первого раза какой "принт" к какой переменной относится становится не просто.
Это плохой код, тут не принты нужны а рефакторинг.
Немного кокретики на примере вашей библиотеки. У кода неприлично высокая цикломатическая сложность. Это проблема. Перепишите на сложность не более 10 и тогда проблема с тем, что непонятно откуда идёт печать изчезнет.
кто разрабатывает веб приложения (и не только) на удаленном сервере
Эту жутко неудобно, но иногда приходится. Я решаю эту проблему юнит тестами. При этом подходе практически ничего не надо удалённо дебажить.
Нажать рефакторинг и сделать руками выглядит быстрей.
Python Smart Execute
Чтобы выполнить файл и продолжить в консоли есть python -i, в пайчарме в настройках запуска есть галочка для этого. Запускается весь файл, а не его часть, но у меня небольшие функции и запускать кусок из них нет смысла.
Rainbow Brackets
Планин, чтобы было удобнее писать плохой код.
Extra Icons
Хотим облегчить процесс кодинга? Но как?
Из хоткеев:
ALT+ENTER quick fix.
double tap on SHIFT (search everywhere), это найти класс, функцию, файл, PyCharm action в одном меню. 4 хоткея в одном.
CTRL + RMB -> got to declaration/show usages (зависит от контекста где кликать).
В меню Help > MyProductivity есть статистика, но мне она кажется странной.
Я использую классы для dependency injection, так как без этого сложно писать юнит-тесты. Если выкинуть тесты, то эти классы можно убрать.
O в SOLID, пропагандирует содавать новый класс вместо изменения существующего. В результате код который создан в процессе эволюции продукта содержит больше классов, чем если бы его написали сразу.
В данном примере тайпхинтинг позволяет только работать с методами BaseClass.
А что там внутри для тайпхинтинга не важно. По большому счёту BaseClass это просто коллекция типа dict. Тип не знает что у него внутри, но знает как к этим внутренностям дять доступ снаружи.
В вашем же примере, с кодом работает машина и ей по большому счёту всё равно там датакласс или нет. Передайте этот тупл в конструктор вашего BaseSensors и внтури творите с ним, всё что хотите.
Попробовал затащить к себе плагины. Что-то даже нашли. Поживу с ними посмотрю как будет работать.
В документации к flake8-commas==2.1.0 рекомендуют использовать black вместо него.
flake8-annotations-coverage==0.0.6 и flake8-annotations==2.9.1 конфликтуют. Первый плагин считает покрытие и не имеет настроек, а второй требует 100% для включённых опций. В flake8-annotations у меня отключена часть требований: ANN101 Missing type annotation for self in method ANN204 Missing return type annotation for special method Поэтому в flake8-annotations-coverage для себя не вижу смысла.
Я flake8 через pre-commit запускаю, поэтому не опубликованные в pip плагины не захотели работать, например git+https://github.com/c0ntribut0r/flake8-grug
У меня сразу в голове возникают вопросы - а что именно скрывается за этими "_" - и будьте уверены, я пойду ковырять этот get_many_params в попытке это понять.
А для других это возможность срезать и не читать лишние переменные.
Спасибо за статью, у меня похожий шаблон для flake8, обогащу его вашими находками.
Я использую совместно с black, это автоматом исключает многие ворнинги.
Сложные аннотации типов можно вынести в переменную. Часто вместо типа Generator можно указать Iterator так проще. Когда я хочу подчеркнуть, что dict который я возвращаю менять не надо, я использую аннотацию Mapping
Когнитивную сложность у себя я отключил. Цикломатическая и когнитивная на маленьких цифрах очень похожа, а так плагином меньше.
Они, наверно, супермены и всегда помнят, что надо закрывать файлы?
Если быть педантом, то нужно еще через try-finally
Для настраеваемых функций часто использую класс с __call__ . Его потом легко подменять в тестах.
Я почти не сомневаюсь, что вы сделали глупость, упустив того потенциального коллегу, который показал вам широту взглядов и умений вместо того, чтобы закапываться в очевидные для него вещи.
Сейчас поправили, а раньше на виндоусе файл при падении программы оставался заблокированным и приходилось что-то делать, чтобы открыть его снова.
Можно упереться в лимит открытых файлов.
Кажется вы лечите симптомы.
Это плохой код, тут не принты нужны а рефакторинг.
Немного кокретики на примере вашей библиотеки. У кода неприлично высокая цикломатическая сложность. Это проблема. Перепишите на сложность не более 10 и тогда проблема с тем, что непонятно откуда идёт печать изчезнет.
Эту жутко неудобно, но иногда приходится. Я решаю эту проблему юнит тестами. При этом подходе практически ничего не надо удалённо дебажить.
У меня мощная машина, в общем я с вами согласен.
Нажать рефакторинг и сделать руками выглядит быстрей.
Чтобы выполнить файл и продолжить в консоли есть python -i, в пайчарме в настройках запуска есть галочка для этого. Запускается весь файл, а не его часть, но у меня небольшие функции и запускать кусок из них нет смысла.
Планин, чтобы было удобнее писать плохой код.
Хотим облегчить процесс кодинга? Но как?
Из хоткеев:
ALT+ENTER quick fix.
double tap on SHIFT (search everywhere), это найти класс, функцию, файл, PyCharm action в одном меню. 4 хоткея в одном.
CTRL + RMB -> got to declaration/show usages (зависит от контекста где кликать).
В меню Help > MyProductivity есть статистика, но мне она кажется странной.
Слишком абстрактно, где граница?
Я использую классы для dependency injection, так как без этого сложно писать юнит-тесты. Если выкинуть тесты, то эти классы можно убрать.
O в SOLID, пропагандирует содавать новый класс вместо изменения существующего. В результате код который создан в процессе эволюции продукта содержит больше классов, чем если бы его написали сразу.
В данном примере тайпхинтинг позволяет только работать с методами BaseClass.
А что там внутри для тайпхинтинга не важно. По большому счёту BaseClass это просто коллекция типа dict. Тип не знает что у него внутри, но знает как к этим внутренностям дять доступ снаружи.
Да, для человека это важно.
В вашем же примере, с кодом работает машина и ей по большому счёту всё равно там датакласс или нет. Передайте этот тупл в конструктор вашего BaseSensors и внтури творите с ним, всё что хотите.
Ну это можно и без датаклассов делать. Просто не распаковывать tuple в переменные.
А где собственно сахар? Вполне себе базовые конструкции языка.
Линтеры в общем подталкивают к такому подходу, там сильно с вложенными ифами не забалуешь.
Спасибо, посмотрю. Вот это точно стоит попробоват: baseline: integrate into a huge project
Это считается помещающейся в 80 символов?
Попробовал затащить к себе плагины. Что-то даже нашли. Поживу с ними посмотрю как будет работать.
В документации к
flake8-commas==2.1.0
рекомендуют использовать black вместо него.flake8-annotations-coverage==0.0.6
иflake8-annotations==2.9.1
конфликтуют. Первый плагин считает покрытие и не имеет настроек, а второй требует 100% для включённых опций. Вflake8-annotations
у меня отключена часть требований:ANN101 Missing type annotation for self in method
ANN204 Missing return type annotation for special method
Поэтому в
flake8-annotations-coverage
для себя не вижу смысла.Я flake8 через pre-commit запускаю, поэтому не опубликованные в pip плагины не захотели работать, например
git+https://github.com/c0ntribut0r/flake8-grug
А для других это возможность срезать и не читать лишние переменные.
Go вообще запрещает объявлять неиспользуемые переменные на уровне компилятора. Но есть один способ обойти это https://go.dev/doc/effective_go#blank
Еще при чтении кода помогают.
Очень неплохое видео про оптимизации производительности Питона, про слоты там тоже есть.
https://www.youtube.com/watch?v=Ix04KpZiUA8
Спасибо за статью, у меня похожий шаблон для flake8, обогащу его вашими находками.
Я использую совместно с black, это автоматом исключает многие ворнинги.
Сложные аннотации типов можно вынести в переменную. Часто вместо типа
Generator
можно указатьIterator
так проще. Когда я хочу подчеркнуть, что dict который я возвращаю менять не надо, я использую аннотациюMapping
Когнитивную сложность у себя я отключил. Цикломатическая и когнитивная на маленьких цифрах очень похожа, а так плагином меньше.
Если быть педантом, то нужно еще через try-finally
Для настраеваемых функций часто использую класс с
__call__
. Его потом легко подменять в тестах.Я зависимости на 3 части разделяю.
- проект
- CI (pytest, линтеры, ...)
- dev, то что нужно на локальной машине, обычно там только pre-commit.
На poetry посматриваю.
Актуально для всех этапов собеседования.
Это тесты на API, там не должно быть сложности. Если всем дают одинаковое здание, то проверка должна занимать минут 10.
Если не времени сделать нормально, надо говорить Нет.
Возможно ему бы стало скучно писать просто тесты.
Генераторы не требуют памяти, но делают больше вычислений.
Создание списка меньше действий, но требует выделения памяти.
Разное железо, версия питона могут немного поменять позиции в списке для худшего случая.
Или можно так: