Python: жёсткий разбор

В качестве, пожалуй, абсолютной противоположности Haskell-у возьмём Python. Критика в его адрес довольно поверхностна, потому что и порог вхождения в язык небольшой. Когда разработчик с одним годом практики начинает выискивать в нём блох, с точки зрения авторитетных программистов конечно это выглядит смешно. Так, любимый мэйнстримом главный «недостаток» Питона — это почему-то отступы. Мой опыт программирования приближается уже к 40 годам, в последнее время я много программирую именно на Python, и вот должен отметить, что отступы — это крайне удобная и наглядная фича языка, которой мне уже сильно не хватает ни в С++, ни в C#.

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

Давайте всё же сделаем акцент на более глубоких вещах и нюансах, вспомнив предварительно заявление автора языка Guido van Rossum — «это был просто хобби-проект»…

В Python множество нюансов исполнения — например, выражения в дефолтных аргументах функции вычисляются, когда она определяется, а не когда вызывается. Не рекомендуется состыковывать строки в классическом цикле, потому что исполнение такого кода будет медленным.
Невозможность статического анализа кода только ухудшает ситуацию с перечисленными проблемами. Добавьте к этому тройные кавычки, двойные подчёркивания, плохую поддержку UTF и юникода…

Объявления локальных и глобальных переменных довольно запутаны и ненаглядны. Разделение доступа к модулям и пакетам практически отсутствует, поэтому скрыть проприетарный код практически нереально. Типа, всё должно быть опенсорсным, но для коммерческих проектов это не очень здорово.

Питон, как известно, не слишком эффективен. Всегда следует опасаться скрытых утечек памяти, особенно когда используешь сложные структуры данных с символическими ссылками.
Global Interpreter Lock, внедрённый для упрощения интеграции с С/С++ библиотеками, сильно мешает параллельной работе — из-за сигналлинга с процессорными тредами он может затормозить выполнение кода даже на одном процессоре. Вдобавок, сам CPython — не потокобезопасный…

Python не предлагает стандартизованный API, что в частности приводит к множеству проблем с версиями сторонних пакетов (как и у Haskell). По большому счёту, Python — это язык программирования в *nix-подобных средах, где уже множество пакетов предустановлено, а развитая система менеджмента пакетов берёт на себя проблемы с версиями. Отсюда — большие траблы с переносимостью даже внутри одной версии Linux. Хорошо бы конечно упаковывать пакеты в дистрибутив, но в мире Python это не принято. Вдобавок абсолютное большинство пакетов для Питона опенсорсные, поставляются под самыми разными лицензиями, и вдобавок к версионным конфликтам часто добавляются конфликты лицензионные.

В стандартном гайде по стилю для Питона не рекомендуется использовать map() и подобные штучки из функционального программирования, хотя они реализованы очень даже неплохо и наглядно. Вместо этого предлагаются кодогенераторы списков с помощью циклов, а в целом, в языке множество условных обозначений и моментов, которые семантически трактуются сильно по разному (например, индексация массивов с помощью «:» ).
Возвращаясь к функциональному программированию, лямбда-функции в Python ограничены одним выражением и не могут включать условия. Кроме того, в Питоне есть фунции, а есть операторы (не возвращающие значение; и даже команда присваивания — просто оператор!), что ещё сильнее ограничивает потенциал лямбд. Более того, в Python 3.* было задепрекачено немало функций высших порядков, а автор языка самодовольно говорил, что вообще не любит хвостовую рекурсию.

На мой взгляд, главный недостаток Питона ровно такой же, как и у всех других динамических языков. Достаточно одной опечатки в имени переменной — и программа будет работать прекрасно много часов, а то и недель, пока баг не проявится в самой неподходящей ситуации. А уж если случайно присвоишь какое-то значение вместо переменной — имени функции… Среда эту запись пропустит без проблем, и потом ловить подобные ошибки чрезвычайно сложно.

Наконец, система типов.
Операции между целыми и строчными данными часто дают странный результат: 2 * «3» = «33»; «2» + «3» = «23»; 2 + «3 » — ошибка. Операции целочисленного и вещественного деления не различаются, но если оба аргумента целые, то и результат будет целым. Ужасно реализованы логические значения — False соответствуют самые разные конструкции (например, «», 0 или []), однако это истинно только при неявном приведении значений, а прямое сравнение «» с False даст неверный результат.
Питон сильно типизирован — но при этом в нём реализована утиная типизация. Эмуляции самых разных типов в документации Питона отведены огромные главы. Списки, таплы, байты и массивы байтов — их мутабельность/иммутабельность надо всегда держать в уме…

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

Поделиться статьей ...Share on Facebook0Share on Google+0Tweet about this on TwitterShare on LinkedIn0Share on VKPrint this page

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *