От переводчика: эта статья — попытка автора показать преимущества (не недостатки) языков программирования Python и Java, а также продемонстрировать двойственность любых сравнений. Что-то, что кажется преимуществом, может оказаться недостатком, и наоборот. Возможно, какие-то моменты могут показаться спорными, но это и к лучшему — в комментариях можно все обсудить, грамотно обосновав свою точку зрения. Статья подходит как для новичков, так и для программистов с опытом.
Java и Python — одинаково популярные языки программирования. Однако Python более продуктивен: в нем меньше объем кода, нужного для решения задачи. Почему же программисты до сих пор работают с Java там, где можно применить Python? Давайте разбираться.
Напоминаем: для всех читателей «Хабра» — скидка 10 000 рублей при записи на любой курс Skillbox по промокоду «Хабр».
Skillbox рекомендует: Образовательный онлайн-курс «Профессия Java-разработчик».
Сравнение эффективности
Сначала давайте обсудим, почему Python более эффективен и позволяет сэкономить время при разработке веб-приложения.
Динамически типизированный
Одна из основных причин того, что Python — более продуктивный язык, — динамическая типизация. Это значит, что нам не нужно ничего объявлять — мы просто задаем переменной имя и присваиваем значение. Python самостоятельно определяет ее тип согласно присвоенному значению.
А вот Java — статически типизированный язык. Все типы переменных здесь должны быть объявлены. Если допустить ошибку, то программа работать не будет или будет, но с проблемами.
Краткость
Python — очень лаконичный язык: в нескольких строках может быть использовано лишь небольшое число слов. А вот Java многословен, в нем многое используется без прямой необходимости. Приведем пример — программу “Hello, World”, написанную на обоих языках.
Java:
public class HelloWorld{
public static void main (String[] args){
System.out.println("Hello, World!");
}
}
Python 2:
print "Hello, world!"
Более того, в Python есть и другие функции, которые позволяют делать код небольшим по объему. Вот еще несколько примеров.
Java:
int x = 5;
int y = 6;
int temp;
temp = x; // temp has the value of 5
x = y; // x has the value of 6
y = temp; // y has the value of 5
Python 2:
y, x = x, y
Меньше Boilerplate code, чем в Java
Python содержит гораздо меньше Boilerplate code, чем Java, что упрощает разработку. Java, где много Boilerplate code из-за многословности языка, иногда ставит в тупик новичков (да и не только их), поскольку для решения простой проблемы требуется приложить значительное количество усилий.
Простота изучения
Немного существует языков программирования, которые были бы проще в изучении, чем Python. Динамически типизированная природа языка и его лаконичность, рациональность делают язык доступным для многих. Java же является более сложным языком для изучения.
Зачем использовать Java?
Ну а теперь давайте посмотрим, почему же Java все еще широко применяется, несмотря на то что работа с ним требует больших усилий, чем с Python.
Статически типизированный
У статически типизированных языков есть недостатки, большая часть которых была описана выше. Но у них есть и достоинства, которых тоже немало. Так, например, Java обеспечивает безопасность типов, которая улавливает все потенциальные ошибки во время компиляции, а не в процессе выполнения, как Python. Таким образом, вероятность появления ошибок уменьшается. В конечном итоге все это упрощает управление большими приложениями. Ошибки во время выполнения (которые появляются при разработке веб-приложений, например, на Python) сложнее идентифицировать и исправлять, чем ошибки во время компиляции.
Кроме того, анализировать Java-код гораздо легче, чем код Python, что полезно в ситуациях, когда над одним проектом работает команда программистов. Java-программисты быстро поймут код друг друга, поскольку все объявлено явно, а вот Python-программисты могут столкнуться с несколькими проблемами при чтении кода веб-приложения. Дело в том, что все определяется или отображается в ходе выполнения приложения, когда становятся известны переменные или сигнатуры.
Производительность и скорость
Собственно, ни Java, ни Python не являются лучшим вариантом для создания высоконагруженных приложений, но у первого языка есть солидные преимущества по сравнению со вторым. Все это благодаря JIT (Just-in-Time Compiler), преобразующему обычный код в машинный язык. В итоге производительность Java-приложений примерно равна производительности того, что написано на С/С++.
Python-разработчики могут использовать Cython и Jython для написания модулей С/С++ и Java-кода под Python. Но это не сильно улучшает общую скорость работы приложений. Python куда медленнее Java.
Портирование и кроссплатформенность
Оба языка являются платформонезависимыми. Однако у Java несколько лучше реализована кроссплатформенная поддержка.
Поскольку Python медленнее Java, разработчики Python часто нуждаются в делегировании некоторых задач библиотекам, написанным на других языках, вроде С++ или Fortran. Следовательно, компаниям, которые используют Python, могут понадобиться персонал, инструменты и инфраструктура для разработки модулей, например, на C или использования существующих библиотек C/C++. Таким образом, вы можете потерять независимость от платформы, которую обещает чистый Python. А вот в случае Java ничего такого не нужно — разработчики работают лишь с Java.
Concurrency vs. Parallelism
Java предоставляет полную поддержку для concurrency с самого начала. Кроме того, есть несколько отличных функций для обеспечения параллелизма и многопоточности. Java также поддерживает параллельное программирование лучше, чем Python. Из-за GIL (Global Interpreter Lock), который ограничивает работу Python одним процессором, этот язык не может предложить того же.
Экосистема
И в Python, и в Java много отличных библиотек и фреймворков. Но Java предпочтительнее для разработки корпоративных приложений благодаря многообразию библиотек и сред, ориентированных на создание высоконагруженных приложений в этой сфере. Они поддерживаются обширным сообществом разработчиков из крупных компаний. Следовательно, программирование корпоративных приложений становится намного проще. Мощная и развернутая экосистема является причиной того, что так много языков ориентированы на JVM: Scala, Kotlin, Clojure, Groovy и т.д. Кроме того, в Java есть мощные инструменты управления зависимостями, такие как Gradle и Maven.
Мобильная разработка
Оба языка используются практически во всех направлениях IT, включая десктопные системы, веб, искусственный интеллект, научные вычисления и аналитику. Да, Python имеет больше преимуществ в такой сфере, как аналитика. Но вот мобильные устройства — это ниша, где доминирует Java.
Примечательно, что Java является одним из официальных языков программирования под Android, конкурируя только с Kotlin. Большая часть приложений, работающих на устройствах Android, включая смартфоны или планшеты, разрабатывается на Java. Язык с успехом используется и во встраиваемых системах.
Хотя мы можем разрабатывать мобильные приложения на Python, используя библиотеку Kiwi, это не лучший способ.
Базы данных
У Java здесь явное преимущество благодаря JDBC (Java DataBase Connectivity). Это платформонезависимый промышленный стандарт взаимодействия Java-приложений с различными СУБД, реализованный в виде пакета java.sql, входящего в состав Java SE. JDBC основан на концепции так называемых драйверов, позволяющих получать соединение с базой данных по специально описанному URL.
В качестве заключения
Java и Python — отличные, мощные языки. У каждого своя собственная ниша, и, как мы видим, оба имеют явные преимущества в той либо иной сфере, так что смысла спорить о том, какой из них лучше, нет. У них просто разная философия. В то время как Java создавалась для того, чтобы снизить вероятность появления ошибки, Python был разработан для того, чтобы программист мог быстрее достичь поставленной цели.
Skillbox рекомендует:
- Практический курс «Мобильный разработчик PRO».
- Прикладной онлайн-курс «Аналитик данных Python».
- Двухлетний практический курс «Я — веб-разработчик PRO».
Комментарии (168)
vilgeforce
12.03.2019 13:16+6Спорно. Динамическая типизация в Питоне меня, например, бесит. Скорость написания овнокода с ней, конечно, выше. Но скорость получения рабочего кода при совершении ошибки — ниже.
«А вот в случае Java ничего такого не нужно — разработчики работают лишь с Java.» — то-то под тот же андроед широко используется нативный код…sshikov
12.03.2019 13:39Ага. И про существование таких библиотек, как JNA (4600 звездочек на github) автор оригинала видимо не слышал. Это помимо JNI.
evocatus
12.03.2019 13:19+1Есть же Clojure. Который обладает ВСЕМИ вышеперечисленными достоинствами Java (потому что работает поверх JVM), кроме статической типизации (которая обладает не только плюсами, но и минусами).
Но основной плюс Clojure в том, что те, кто пытается писать в ОО парадигме, но на самом деле не понимает её (99% выпускников вузов, которые не слишком интенсивно занимались самообразованием и им не повезло узнать кто такой Алан Кей, что такое Smalltalk, как расшифровывается SOLID), про Clojure даже не слышали, а даже если слышали, не смогут на нём писать. А смогут на нём писать, когда выучат и поймут такие вещи, которые сделают их более просветлёнными.chupasaurus
12.03.2019 13:32+3Есть же Emacs Lisp. Который обладает ВСЕМИ вышеперечисленными достоинствами Clojure (потому что тоже диалект Lisp), кроме бесконечного источника фрустрации в виде JVM (которая обладает не только плюсами, но и минусами).
Могу и дальше продолжить, но суть проста: у любой технологии есть плюсы и минусы, выбор — за человеком. И не существует тьюринг-полных языков, абсолютно защищённых от стрельбы по ногам и на которых невозможно написать неподдерживаемый код.sshikov
12.03.2019 15:30Вы правы — если забыть о чем пост. А если вспомнить — то тут говорится о якобы большей лаконичности питона. Но при этом про все остальные языки, включая кложу, резко забывают (даже если их упомянули абзацем выше).
И кстати, слово ВСЕМИ тут лишнее. У вас. Работа поверх JVM тоже может быть достоинством, которого Lisp на другой платформе лишен. Недостатком тоже может.
Что у JVM есть недостатки — не вопрос (хотя в чем может быть " бесконечный источник фрустрации" лично мне не понять).
tuxi
12.03.2019 13:29+1Python содержит гораздо меньше Boilerplate code, чем Java, что упрощает разработку. Java, где много Boilerplate code из-за многословности языка, иногда ставит в тупик новичков (да и не только их), поскольку для решения простой проблемы требуется приложить значительное количество усилий.
грамотно написанный на java код размером в 10..50 строк, гораздо лучше подходит под понятие «самодокументированный» код, нежели чем 5..10 строк на Питоне, которые к тому же в большинстве случаев являются вызовом каких-либо библиотек.
PS: Когда передо мной встал вопрос «какой язык (помимо java) использовать для быстрого написания простеньких тестовых утилит, прототипов и тп», я опять же выбрал golang, а не Питон и доволен аки слон.SirEdvin
12.03.2019 13:41грамотно написанный на java код размером в 10..50 строк, гораздо лучше подходит под понятие «самодокументированный» код, нежели чем 5..10 строк на Питоне, которые к тому же в большинстве случаев являются вызовом каких-либо библиотек.
Лично мне так не кажется. Возможно дело в том, что и там, и там можно писать немного запутано?
tuxi
12.03.2019 13:47Можно, но у Питона больше "соблазнов" так сделать.
ArsenAbakarov
12.03.2019 17:03Первостепенно должен быть порядок в голове, писать то можно все что угодно и где угодно
sshikov
12.03.2019 13:51Вероятно, цель поста — натянуть сову на глобус. Что характерно, тут упомянуты все или почти все языки под JVM, употребление которых напрочь лишает питон преимуществ в лаконичности. Это не догадка — я это проверял на примере груви раз 10. Ну то есть, если у меня есть возможность использовать JVM (что не очевидно), то я просто беру груви (котлин, кложу, скалу, назовите сами), и получаю ровно те же 5-10 строк. И все преимущества со мной.
Caracat
12.03.2019 13:32Я бы добавил, Питон сейчас занимает нишу, как Бейсик в 80-90-е, — низкий порог вхождения, чтобы начать кодить и быстро получать результат типа лабы и т.д.
tuxi
12.03.2019 13:37Вот тоже хотел в своем комментарии указать на эту «похожесть» ситуации, только я бы еще паскаль добавил бы. Питон становится языком для старта. Гуд. Но только, как мне кажется, перейти с Питона на статически типизированный язык сложнее, нежели чем наоборот. Вот это лично мне не нравится.
AndyKorg
12.03.2019 13:48Паскаль отлично подходит для начала изучения программирования. Никакой магии и стимулирует думать в строгом математическом стиле. У тех кто начинал изучать программирование на Си более длинный путь к той же SOLID, но это касается только профессиональных программистов. Для непрофессионалов питон как первый язык самое то, Java как первый язык скорее всего не подходит никому.
tuxi
12.03.2019 14:25+1Почему же, Object Pascal достаточно академично следует модели ООП. Смоллталк наверное был бы лучше (я б даже сказал, экстремально лучше), но сейчас по-моему его уже давно не изучают в вузах.
nikolayv81
13.03.2019 19:31Паскаль не подходит, он и компилируемый и со статической типизацией, а если вспомнить использование библиотек от borland то он ещё больше похожим на java чем на python будет.
Angmarets
13.03.2019 19:37Хотел возразить, что паскаль всю жизнь был интерпретируемым(ну по крайней мере, все те 5 лет, что я изучал его в школе.) Как оказалось, у него есть два варианта:
При этом для многих языков существует различие в производительности между компилируемой и интерпретируемой реализацией.
Большое количество языков, включая BASIC, C, Lisp, Pascal и Python, имеют обе реализации
ru.wikipedia.org/wiki/Интерпретируемый_язык_программированияnikolayv81
13.03.2019 20:08Я честно говоря не знаю откуда эта запись в википедии и в каком году вы учились в школе, но интерпретируемой версии паскаля я не видел, возможно она(и)/и была(и), и возможно есть сейчас, но сама концепция указателей на память не ложится в концепцию интерпретируемых языков.
p.s. это если не вспоминать про версии delphi, в их интерпретируемость я не верю :)Angmarets
13.03.2019 21:06Учился в начале 2000-х, как назывался интерпретатор не помню. В голове крутиться Borland Pascal, но что-то я сомневаюсь. Конечно же никакого Delphi и вообще ООП. Вики знает как минимум про один интерпретатор и он таки да, создан для обучения программированию.
ru.wikipedia.org/wiki/Visible_Pascalmayorovp
14.03.2019 08:58Borland Pascal — это более дорогой вариант Turbo Pascal, который был первым компилятором Паскаля в машинные коды (из-за чего и «заслужил» название «Turbo»)
До этого Паскаль компилировался, но не в машинные коды, а в p-код, который уже интерпретировался.
shiru8bit
12.03.2019 13:58+1Возможно я недостаточно знаю Python (написал десятки небольших скриптов), но меня всегда напрягает в нём разбиение на блоки посредством отступов, причём обязательное. Очень часто бывает неудобно искать начало блока (пишу в обычном Notepad++). Ещё регулярно в разных скриптовых языках доставляет неудобство отсутствие классического switch case, хотя, вероятно, это специфика решаемых задач.
flx0
12.03.2019 14:08+2Очень часто бывает неудобно искать начало блока
Но ведь отступы для того и придуманы, чтобы блоки было сразу видно. Как они могут в этом мешать?
отсутствие классического switch case
elif его прекрасно заменяет при нормальном программировании, а при ненормальном… Ну,
def case_0(): ... def case_1(): ... def default(): ... switch = {0: case_0, 1: case_1} switch.get(x, default)()
например.
shiru8bit
12.03.2019 14:13+1Очень просто, кода и вложенных условий и циклов в нём может быть довольно много.
Аппеляция к нормальному программированию так себе аргумент, честно. Примерно как переход на личности.flx0
12.03.2019 14:22Не переход на личности, а предупреждение о том, что приведенный пример — не самый читаемый код, и от такого надо по-возможности воздерживаться, если нужен именно switch-case. Но возможность в принципе есть.
shiru8bit
12.03.2019 14:36Так оба варианта, и elif, и приведённая конструкция, и тем более словари довольно нечитаемы и неудобны в поддержке, если применяются там, где нужен просто длинный switch. Не знаю, чем он так не угодил авторам скриптовых языков, но они всё время стремятся либо исключить его вообще, либо изменить логику работы (типа switch без break и fallthrough в Haxe). Но придумали-то его не на пустом месте, и применения находятся, пусть и редко в современных реалиях — можно было бы не убирать его совсем.
mayorovp
12.03.2019 14:14+2Но ведь отступы для того и придуманы, чтобы блоки было сразу видно. Как они могут в этом мешать?
В крупных портянках — запросто.
def чтототам(): строка1 if условие2: строка3 while условие4: строка5 иещё100строк строка6 нуигде(искать,начало,этого+блока)
nikbond
12.03.2019 14:21Подсветка табуляции стрелочками вроде решает этот вопрос. По крайней мере, если сравнить с си-скобочками {}
tuxi
12.03.2019 14:32+2на коленке в срочном порядке открываешь код в каком нить редакторе,
а там вот такая радостьи сколько тут табуляторов, сиди считай. Хорошо если на «курьер» есть возможность переключиться. А скобки даже far из коробки посвечивать умеет.dimm_ddr
12.03.2019 15:18Я вроде бы и понимаю вашу проблему, но для меня во всех этих примерах совершенно очевидно где начало блока, где конец, а где вложенный блок. У меня с питоном проблемы были только когда строки слишком длинные и заворачиваются на следующую, далеко не во всех редакторах это нормально реализовано. При этом я работал с питоном и с notepad++ и с JB IDE и даже через cat линуксовый на скрипты смотрел. Скобочки, при желании, можно гораздо менее читабельно расставить, а табы/пробелы они всегда примерно одинаково выглядят.
tuxi
12.03.2019 16:08+1И все же, почему отступы? Не большой знаток истории питона, просто интересна мотивация такого решения у создателей языка.
mayorovp
12.03.2019 16:12Мотивация как раз очевидна: хорошие программисты всё равно дублируют скобки отступами, так зачем в языке лишние элементы?
tuxi
12.03.2019 16:15ну вот в экосистеме golang этим может заниматься специальная тулза, а для java в IDE есть волшебные кнопочки. Но их можно нажимать, а можно не нажимать. И логической ошибки не будет.
ApeCoder
13.03.2019 08:42Когда «не нажимать» ошибка как раз будет — отступы будут давать ложную информацию о вложенности. А человек в перовую очередь смотрит на них
HEKOT
12.03.2019 18:30Иногда текст расползается в высоту непозволительно. И тут начинается проблема с сотней строчек.
Nikobraz
12.03.2019 20:51И тут отступы выигрывают, не нужна подсказывающая IDE, промотал вверх, посмотрел на необходимый уровень вложенности.
Больше бесит вечная проблема Tabulation versus 4 Spaces, когда в одном файле смешаны табы и пробелы, то начинаются проблемы.zzzmmtt
13.03.2019 08:24В нормальной IDE без разницы, отступы или скобки, подсветка отступа/скобок должна быть по умолчанию, тогда явно виден уровень вложенности.
А tab vs 4 spaces проблема надуманная, решается либо следованием общепринятым стандартам (PEP-8 для Python, PSR-2 для PHP, etc), либо соблюдением code style guide в конкретной компании, ежели таковой отличается от PEP/PSR/etc.
defuz
12.03.2019 16:14+11. Форсить разработчиков форматировать свой код (в 1991 не все считали нужным делать это всегда и единообразно).
2. Уплотнение кода: чтобы как-можно больше смысла помещалось на квадратный пиксель (отдельная строка на закрывающуюся скобку не нужна), при этом без деградации в ASCII-art на Perl – блоки придется делать многострочными, а не однострочниками.tuxi
12.03.2019 16:20отдельная строка на закрывающуюся скобку не нужна
есть два стиля, скобка на новой строке и скобка на той же строке
try { } catch() { }
defuz
12.03.2019 16:331 try { 2 if condition { 3 return 0 4 } 5 do_work() 6 } catch() { 7 handle_error() 8 }
1 try: 2 if condition: 3 return 0 4 do_work() 5 except: 6 handle_error()
tuxi
12.03.2019 16:37Если внутри блока try логики на 10..20+ строк, то сколько экрана в % мы сэкономим?
defuz
12.03.2019 16:43Речь про любые блоковые синтаксические конструкции (if, for, while, функции, классы, методы и т.д.), которые скорее всего будут встречатся в этих 10-20 строках, и на каждой такой конструкции мы экономим одну строку.
HEKOT
12.03.2019 18:40Я как-то несколько раз проводил эксперимент: в реальном тексте (не моём) формат типа
void func() { if (condition) { act1(); act2(); } else { act3(); act4(); } }
заменял на
void func() { if (condition) { act1(); act2(); } else { act3(); act4(); } }
Ну и ещё в этом роде, типа короткие однооператорные if в одну строчку и пр…
Из 500 строк получалось примерно из 400 (из 2000, соответственно, 1600). Кроме того, на экране помещалось гораздо больше. Мне это важно, так как зрение посредственное, ставлю относительно крупный шрифт.
suguby
14.03.2019 12:08От отступов, точнее от соблюдения стиля кода PEP8, есть другие далеко идущие выгоды.
Например, связка отступов и ограничения в 80(120) символов на длину строки дает индикатор сильной вложенности кода. Если программисту уже тесно вблизи 120 символов, что-то пошло не так. И надо выносить куски кода в отдельные методы/функции, что дает бОльшую гибкость при развитии проекта.
Кмк, жесткое требование форматирования кода подталкивает к написанию чистого кода.
nikolayv81
13.03.2019 20:30ИМХО данный пример очень короткий, поэтому проблем "почти" нет, почти потому-что выделяя скобочками (или, как вариант, begin… end-ами) я сам выбираю как мне удобно видеть код (от варианта python-а до варианта отлаженные повторяющиеся на 95% блоки одной строкой (мы же не про большие проекты на python а про небольшие куски логики для прототипирования?), а в python у нас вариантов особо нет.
p.s. про длину портянок, я понимаю что это неправильно и т.д. но когда люди пишут простые утилиты они редко разбивают тело на функции и т.п., что может приводить к зашкаливанию "ширины" кода на python из-за отступов, также многие, даже текстовые, редакторы умеют сворачивать блоки в скобках но не умеют сворачивать блоки в python коде (и стандартный редактор под linux (idle) тоже не умеет), что в сумме делает редактирование "часто не удобным".dimm_ddr
14.03.2019 09:44а в python у нас вариантов особо нет.
Вам никто не запрещает в питоне в одну строку писать блок через ";". Так что варианты есть и в питоне.
не умеют сворачивать блоки в python коде
Кроме собственно idle и каких-нибудь nano, vi я даже и не вспомню кто еще не умеет сворачивать блоки в питоне. Все нормальные IDE его поддерживающие (то есть все кроме idle) — умеют. Notepad++ и sublime — тоже умеют причем из коробки. Блокнот не умеет конечно, но он и скобки не умеет. У вас есть пример редактора который знает про скобки, но не знает про питон?
ApeCoder
13.03.2019 08:41Ага. Или какой-нибудь форум считает пробельные символы незначимыми и сводит все к одному пробелу при копипасте. Правда, для любого X можно придумать условия, когда оно не работает.
ApeCoder
12.03.2019 14:26Мне кажется, это недостаток «иещё100строк» а не питона. В любом случае надо либо ручками считать отступы/скобочки или чтобы это делал инструмент.
При этом одними скобками обойтись нельзя, а одними отступами — можно.mayorovp
12.03.2019 14:29-1Да, согласен, это недостаток «иещё100строк». Но Питон от этого недостатка всё равно не спасает.
ApeCoder
13.03.2019 08:47Во-первых, в каком-то смысле спасает из-за меньшего количества кода для того же смысла. Во-вторых, речь не о том, что спасает а о том, что фигурные скобки никак не помогают.
defuz
12.03.2019 15:48Редактор вам в помощь (обратите внимание на вертикальные линии):
mayorovp
12.03.2019 15:54Не помогают они, когда «ещё строк» и правда 100, а не 4.
DMGarikk
12.03.2019 16:00а как вам скобочки помогут в данном случае? вы визуально запомните скобочку, а через 20 страниц вниз узнаете что «именно эта» скобочка — закрывающая?
mayorovp
12.03.2019 16:03Я установлю курсор на скобочке, и через 20 страниц вниз увижу скобочку другого цвета.
zzzmmtt
12.03.2019 16:06Так и эти линии в нормальных редакторах подсвечиваются. Во всяком случае в phpstorm это есть.
mayorovp
12.03.2019 16:09Если они подсвечиваются — да, эта подсветка помогает. Именно подсветка, а не язык.
zzzmmtt
12.03.2019 16:12Мне на самом деле тоже не нравится эта особенность питона, то что отступ фактически является частью синтаксиса языка. Но я не питонист, хотя при необходимости прочитать код на питоне смогу, не исключено, что и писать на нём смогу без особых проблем.
defuz
12.03.2019 16:06Тоже самое я делаю в питоне: ставлю курсор в начале «строка6» и листаю вверх пока не упрусь в курсором в начало строки «while ...».
В случае с питоном нет необходимости считать открывающиеся/закрывающиеся скобки походу, а потому и подсветка парных скобок не нужна.
nikolayv81
13.03.2019 20:39Почти все редакторы которыми пользуюсь умеют их сворачивать, кроме idle, плюс бывают ещё комментарии.
fireSparrow
12.03.2019 16:55Имхо, внутри if или while не стоит писать портянку на 100 строк в любом случае — даже если у вас язык со скобочками.
nikolayv81
13.03.2019 20:42А что делать если по факту такой алгоритм, нет на питоне мне такое делать не приходилось, только на sql :) (справочники не предлагать, и так в терадате не быстро работает ;) )
ApeCoder
13.03.2019 21:44Это не «алгоритм такой», а язык либо компилятор настолько убогий что не поддерживает удобство и эффективность.
fireSparrow
13.03.2019 22:42Такое нужно выносить в отдельную функцию. Или даже не в одну функцию.
nikolayv81
13.03.2019 23:46Просто это был пример из жизни, который может быть неудобен в случае использования подхода с отступами (выносил из sql запроса в функцию разбор данных по двум параметрам (строкам), банальный парсинг текста с сотней масок, он реально занимает 100+ строк case when.., в два уровня. ).
mayorovp
14.03.2019 09:08Функции в том же SQL могут быть барьерами оптимизации. Видел я реализацию самозамедляющейся очереди сообщений за ?(N2) на операцию (где N — общее число прошедших через очередь сообщений). Один из множителей N в этой асимптотике взялся исключительно из-за применения функций…
ArsenAbakarov
12.03.2019 17:04Интересно посмотреть на тесты к этому коду
mayorovp
12.03.2019 17:10Когда я последний раз смотрел на такой код, тестов к нему я не видел…
Кстати, портянки с вложенными классами прекрасно тестируются — но столь же плохо читаются.
AndyKorg
12.03.2019 16:00А вот прям счас случай — нужно посмотреть код в продуктиве. Система контроля версий недоступна, что бы попасть на продуктив была согласована херова туча бумажек. И вот я на проде! Обана! А из редакторов только Блокнот.
alemiks
12.03.2019 16:58+1
если инвертировать и сделать return, то -1 ступенька «лесенки»if условие2:
попробуйте рефакторинг «Extract method»иещё100строк
TL;DR; код, который криво написан, одинаково кривой и в java, и в python, и в c#, и в javascriptmayorovp
12.03.2019 17:13если инвертировать и сделать return, то -1 ступенька «лесенки»
Это был фрагмент кода, там внизу может быть ещё пара таких же операторов.
попробуйте рефакторинг «Extract method»
… а потом попробуйте придумать новому методу имя :-)
Если серьезно, то такие портянки обычно возникают при совмещении нескольких алгоритмов в одном. И далеко не всегда их можно взять и разделить методом «Extract method», часто нужен «Extract generator», которого IDE делать не умеют...
dopusteam
12.03.2019 14:09+2"А вот Java — статически типизированный язык. Все типы переменных здесь должны быть объявлены. Если допустить ошибку, то программа работать не будет или будет, но с проблемами."
Программа скорее всего не скомпилится.
А вот если допустить ошибку в Python, то как раз таки" программа работать не будет или будет работать с ошибками"SirEdvin
12.03.2019 14:23Программа скорее всего не скомпилится.
Слышали ли вы о NullPointerException?
Angmarets
12.03.2019 14:58+2Это ж как нужно выпендриться с типами, кастами и иерархией чтобы из-за неправильного типа получить NPE? Максимум, что вылезет — ClassCastException
SirEdvin
12.03.2019 15:26Это к тому, что вам ничего не мешает передать в типизированную функцию
null
и она абсолютно так же упадет в рантайме, если проверка наnull
не была добавлена.dopusteam
12.03.2019 16:07Ещё раз
«А вот Java — статически типизированный язык. Все типы переменных здесь должны быть объявлены. Если допустить ошибку, то программа работать не будет или будет, но с проблемами.»
Если допустить ошибку в python — то программа тоже либо работать не будет, либо будет работать с проблемами, это не особенность статической типизации.
Но при этом, в Java большАя часть ошибок на этапе компиляции отпадёт.
А вообще вы сравниваете тёплое с мягким, 'Почему люди едят апельсины, если можно забивать гвозди молотком'
Beholder
12.03.2019 14:14+2Скажите автору — пусть проснётся, сейчас 2019 год. Действительно нет смысла использовать многословную Java когда есть лаконичный Kotlin.
sshikov
12.03.2019 16:47В 2009 примерно, а то и раньше, все было уже точно также. Не нравится вам многословность — берете лаконичный груви. Что-то потеряете, но лаконичность точно получите. В списке языков, поддерживаемых JSR-223 уже тогда были десятки, и они все были доступны любому, кто хотел лаконичности.
Котлин только добавил разнообразия в этом смысле, это уже вишенка на торте, если угодно.
VIkrom
12.03.2019 17:08-1Kotlin сегодня есть, завтра нет. Сколько уже этих убийы жавы было.
Whuthering
12.03.2019 19:23Этому «очередному убийце Java» теперь оказывается поддержку лично Google со всей своей Android-экосистемой.
dimm_ddr
13.03.2019 11:43-1Ну так-то гугл славится своей привычкой закапывать полезные и удобные пользователям проекты. Нет никаких гарантий что через 5 лет они не решат развивать что-то новое и забросят котлин.
Aquahawk
12.03.2019 14:32Напоминает крики школьника на тему того что Pascal строго типизирован, а basic нет, и типа так проще.
dididididi
12.03.2019 14:40Каждый раз, когда я слышу про лаконичность языка, пытаюсь вспомнить хоть один случай, когда у меня скорость программирования упиралась в скорость печати)))
Londoner
12.03.2019 16:01Не знаю, не знаю… Обычно один и тот же код на питоне получается в среднем в два раза быстрее, чем на джаве. У кого какие наблюдения насчёт разницы в скорости разработки?
tuxi
12.03.2019 16:13А какое кол-во строк в проекте? 100т или уже по взрослому, около 500т? :) мелкие вещи быстро и просто можно делать на куче языков, а вот крупные — далеко не на всех.
sshikov
12.03.2019 16:51Я переписывал строк 500 с питона на груви. Пару-тройку лет назад. Получилось примерно в два раза короче. Так что про лаконичность — это все сказки. Груви в посте упоминается? Упоминается. Так почему я не могу его взять вместо питона?
Так что даже про мелкие — почти все мимо.
Revertis
13.03.2019 00:22У кого какие наблюдения насчёт разницы в скорости разработки?
Не знаю как у других, но в Java я постоянно пишу с автодополнением, и в написании одной строки порой нажимаю Enter несколько раз.
И часто пользуюсь intension'ами, когда вместо
набирается простоfor (String s: someList) { }
и нажимается Enter.someList.for
defuz
12.03.2019 16:51Справедливости ради, лаконичность – это не только скорость печати, но и скорость чтения (восприятия). Код написанный 1 раз потом будет 10-100 раз прочитан, и как раз скорость восприятия уже значимо сказывается на вашей работе.
dididididi
12.03.2019 21:14+2Ну про скорость чтения я ваще не жалуюсь. Код не становится быстрее понимаем, если он короче написан. Банальный пример с троичным оператором
String r= f!=null?f==g?g:f:g;
Anthrax_Beta
12.03.2019 14:53+1Кто-то может не согласиться, но я считаю что у каждого языка программирования есть некая своя ниша и свои цели, для которых они создавались.
saipr
12.03.2019 15:00-1Хотел написать, а почему вы умалчиваете про Tcl?
Но когда прочитал внимательно вашу аргументацию про Java в сравнении с Python (а Python и Tck ягоды отного поля), все стало понятно. Возразить тяжело. И статья понравилась.
Anton23
12.03.2019 15:08+3Одна из основных причин того, что Python — более продуктивный язык, — динамическая типизация.
Пфф,DMGarikk
12.03.2019 15:21Помню времена когда бейсику ставили огромный минус за то что у него есть тип Variant… более того я совсем недавно учавствовал в какомто споре о языках и до сих пор ему это припоминают… хотя казалось бы, питон и js — современные языки… но там не… там типа норм
p.s. люблю java, но в данный момент пишу на питоне (и печалюсь)zzzmmtt
12.03.2019 16:07А как там с goto? Бейсику тоже за goto минус до сих пор ставят?
DMGarikk
12.03.2019 16:21как ни странно но да :) причем очень мало кто помнит (скорее уже никто не видел) чем goto и gosub плохи
забавно начинать спорить что лучше паскаль или бейсик для обучения программированию в 2019 году :) такие доводы странные люди выдумывают (лишь бы современный язык не брать)zzzmmtt
12.03.2019 16:26Многие ещё забывают, что в ассемблере вагон goto, только называется иначе, jmp, jz, jnz, jne и т.д., и там это вроде минусом не считается.
Pusk1
12.03.2019 15:26Не встречал проблем при работе с БД на Python в последние годы, как и с доступом к данным. Стек Hadoop больше любит Java, но и с Python дружит неплохо.
sshikov
12.03.2019 15:33Я встречал. В каком-то из питоновских драйверов MS SQL колонки типа varchar были ограничены 100 символами (и это было задокументировано). Я в осадок выпал от такого. 2017 год был на дворе, ни один JDBC драйвер такой дури не содержит.
nikolayv81
13.03.2019 21:32С другой стороны Oracle Number (который 38), и как с ним нормально работать через jdbc (дв хоть и не с java а с c#, но там удобная библиотека от oracle есть)?
sshikov
13.03.2019 21:57Да как-то не замечал особых проблем. Отображается в BigDecimal.
nikolayv81
13.03.2019 23:51Но ведь по сути это тип из отдельного модуля, т.е. вполне может быть реализация jdbc драйвера не учитывающая такой особенности.
sshikov
14.03.2019 13:38Для оракла? По-моему для оракла вообще альтернативных реализаций нет в природе.
vlad9486
12.03.2019 15:27-5Одна из основных причин того, что Python — более продуктивный язык, — динамическая типизация. Это значит, что нам не нужно ничего объявлять — мы просто задаем переменной имя и присваиваем значение. Python самостоятельно определяет ее тип согласно присвоенному значению.
Нет. Это значит что тип переменой может поменяться во время выполнения. Питон самостоятельно определяет тип потому что он питон, а не потому что динамически типизирован.
А вот Java — статически типизированный язык. Все типы переменных здесь должны быть объявлены. Если допустить ошибку, то программа работать не будет или будет, но с проблемами.
При программировании на любых языках лучше не допускать ошибок, типизация и здесь ни при чем.Whuthering
12.03.2019 16:04Питон самостоятельно определяет тип потому что он питон, а не потому что динамически типизирован.
WUT? То есть по-вашему связывание переменной с типом в момент присваивания не имеет никакого отношения к динамической типизации? Забавно.
При программировании на любых языках лучше не допускать ошибок, типизация и здесь ни при чем.
Статическая типизация позволяет успешно избежать определенного круга ошибок, что дает существенный выигрыш в скорости разработки и стабильности ПО.vlad9486
12.03.2019 16:14связывание переменной с типом в момент присваивания не имеет никакого отношения к динамической типизации?
В статически типизированных языках это тоже есть. Называется вывод типов.
Статическая типизация позволяет успешно избежать определенного круга ошибок, что дает существенный выигрыш в скорости разработки и стабильности ПО.
Ну да. И в мыслях не было с этим спорить. Мне показалось что автор писал о том что на питоне можно где-то сделать ошибку и с этим жить. Оно то можно, и оно иногда даже сразу не заметно. Но это халтура какая-то а не программирование.Whuthering
12.03.2019 16:21В статически типизированных языках это тоже есть. Называется вывод типов.
Добавьте в формулировке выше «в момент присваивания, а не в момент объявления переменной» или «в момент присваивания в run-time».
Статические языки даже с выводом типов в такое либо не могут, либо не приветствуют (если не считать всякие специфичные типы variant/any/dynamic/итд).vlad9486
12.03.2019 16:29Язык Rust.
let s = "hello"; // тип &str let s = s.to_owned(); // тип String let s = 5; // тип i32 fn foo(i: i32) -> Bar { ... } let temp = (0..5).map(foo).collect::<Vec<_>>(); // тип Vec<Bar>
Типизация все равно статическая потому что каждый новый биндинг затеняет предыдущий. То есть у нас тип переменной не меняется, но каждый раз меняется сама переменная, прошлый биндинг затеняется и вместо него в скоупе появляется новый с таким же именем.
Я не до конца понял что вы хотите, но похоже что что-то такое.
mayorovp
12.03.2019 16:15То есть по-вашему связывание переменной с типом в момент присваивания не имеет никакого отношения к динамической типизации?
Ага, такая штука называется "вывод типов".
zzzmmtt
12.03.2019 16:04Нет. Это значит что тип переменой может поменяться во время выполнения. Питон самостоятельно определяет тип потому что он питон, а не потому что динамически типизирован.
[sarcasm]PHP самостоятельно определяет тип, потому что это PHP, а не потому что динамически типизирован.[/sarcasm]
Ну и по второму вашему утверждению — не допускать ошибок это конечно хорошо. Только вот динамическая типизация очень легко помогает допускать эти ошибки.
На самом деле каждой задаче — свой инструмент, холиварить смысла нет, есть смысл учиться выбирать нужный инструмент, при необходимости изучать новый инструмент, тем самым развиваясь как специалист. Где-то лучше использовать Java, где-то возможно выиграет python, php, *sh-скрипты, etc. Где-то динамическая типизация может быть полезной, где-то наоборот только вредить будет.vlad9486
12.03.2019 16:14ОМГ. Почему все решили что я за динамическую типизацию топлю?
Хаскель вон тоже может вывести тип, но он статически типизирован. А в java не завезли. Это не зависит от типизации же.zzzmmtt
12.03.2019 16:29Я за всех не решал, мне лично показалось странным утверждение про «питон определяет, потому что он питон, а не потому что динамическая типизация». Я, заметьте, спокойно отношусь как к статической, так и к динамической.
vlad9486
12.03.2019 16:36Определять можно и со статической и с динамической типизацией. Значит питон это делает по каким-то другим причинам, похоже что потому что его так реализовали, потому что он питон. Утверждение может выглядит странным, да.
Londoner
12.03.2019 16:06Вот почему все думают, что статическая типизация — это панацея от ошибок, что они все магическим образом поймаются на стадии компиляции? По-моему, она помогает увидеть максимум 10% ошибок. Всё остальное всё равно вылезет только в рантайме, если тесты по-уму не писать.
vlad9486
12.03.2019 16:18Если статические типы вообще везде, даже в примитивах ОС, если они достаточно развитые, что-бы в них помещалось много логики, то это близко к панацеи. Но вылазят другие проблемы. Нужен баланс.
YuryB
12.03.2019 20:44ну это совсем откровенный недоброс до вентилятора. даже писать что-то по теме не интересно, т.к. все и так всё понимают что и почему.
Maccimo
13.03.2019 00:04+2Откуда пошла эта мода на рассказы про «многословность» Java?
Псле освня слпго дстпльцвго мтда лкнчнсть трят свй шрм.ApeCoder
13.03.2019 13:18Многословность влияет не только на запись но и на чтение.
Если посмотреть пример:
Java vs Kotlindididididi
13.03.2019 14:04Эмм… что касается первого примера, то на java можно писать так, хотя и не принято, я горячо за эту практику
class Person{String name;} printName(person.name).
ну или lombok: data class Person{private String name;}ApeCoder
13.03.2019 14:11Да, так можно, но это не то же самое.
Про lombok я в курсе в общих чертах. Это стандартизировано? Насколько инструменты это поддерживают? (например rename refactoring поймет, что надо переименовать getName и все, что его использует?)dididididi
13.03.2019 15:54lombok дефакто стандарт стал, как спринг. rename норм, ломбок при компиляции дописывает эти методы, раньше проблемы с дебагом были, но вроде порешали.
ApeCoder
13.03.2019 19:22rename норм, ломбок при компиляции дописывает эти методы,
тык в этом — то и проблема — для этого надо чтобы весь джавовский тулчейн знал про то, что ломбок генерирует эти методы — я поискал — нашел старые эклипсовые баги на эту тему.
tuxi
13.03.2019 11:05Сегодня как раз вышла хорошая статья про стоимость лаконичности питона
"Проведенный эксперимент показывает интересные результаты. С одной стороны, при таком подходе производительность выровнялась, но с другой — пропала лаконичность"
sshikov
13.03.2019 11:33+1. Когда видишь разницу в 50 раз (а для меня эти результаты и вовсе не были неожиданными) — то в общем и вопросов не возникает, таких какой поставлен в заголовке.
fireSparrow
13.03.2019 11:40-1Только там идёт речь конкретно про Apache Spark.
Примеры в статье хорошо показывают подводные камни использования питона именно для спарка, но они вообще ничего не говорят про питон сам по себе.sshikov
13.03.2019 12:22Вообще-то спарк только усугубляет известные проблемы питона с производительностью. Но они и без него никуда не денутся. Иногда их можно решить, иногда нет. Иногда получаемый результат приемлем, иногда нет.
И еще статья хорошо показывает лаконичность питона в сравнении со скалой — и там видно, что это точно миф, скала как минимум настолько же выразительна, или лучше.
fireSparrow
13.03.2019 12:29Кто поставил минус комменту и в карму, объясните, пожалуйста, — за что?
Неужели тот факт, что питоновский код нужно отдельно переделывать под спарк, действительно как-то характеризует питон сам по себе? И неужели противоположное мнение действительно нужно наказывать минусами в карму?sshikov
13.03.2019 13:13Про карму ничего не знаю, а коммент я — и выше объяснил, почему. Кстати, питоновский код не нужно переделывать под спарк — как видно из того поста, он и так работает. Его нужно переделывать чтобы он не тормозил. Это не тоже самое.
tuxi
13.03.2019 12:34Ну там же написано, как только отказались от библиотеки, производительность выросла, но код перестал быть лаконичным. Это и есть те самые плюсы и минусы питона. Часто лаконичность питона получается за счет многочисленных библиотек, а взамен мы получаем понижение гарантии производительности.
ApeCoder
13.03.2019 13:06А вы уверены, что это стоимость именно лаконичности, а не чего-то еще? Например, динамической типизации?
В статье сравнивается со Скалой, а не с джавой.
Например, переведите это на джаву:
case class AucAccumulator(height: Int, area: Int, negatives: Int)
sshikov
13.03.2019 13:22Дело в том, что основная ошибка автора (не переводчика) состоит в том, что он считает скалу (груви, кложу, котлин) чем-то отдельным от java. В то время как (ну, по крайней мере для меня и многих людей вокруг) это часть экосистемы вокруг JVM. И я легко, не в первом, а скорее в десятом проекте, уже лет 10 как, с момента появления груви, пишу сразу на двух-трех языках. Мне не надо «это переводить на джаву», я просто этим воспользуюсь.
Вас не смущает, что для использования например nympy нужно сделать pip install? То есть, установить что-то (для случай кластера это особо актуально, потому что это нужно накатить на каждый его узел).
А мне для использования скалы или груви в общем случае и этого не нужно. Если мне в экосистеме JVM нужна лаконичность — у меня ее сколько угодно, и очень давно. Есть обширный выбор лаконичных языков, и многие из них лучше питона (опять же — на мой личный вкус, но мы вполне можем это обсудить, и я это утверждение могу легко подтвердить фактами).
>Например, динамической типизации?
А это не следствие одно другого? В смысле — лаконичность же она в том числе от того, что не нужно типы указывать, например.ApeCoder
13.03.2019 13:41Дело в том, что основная ошибка автора (не переводчика) состоит в том, что он считает скалу (груви, кложу, котлин) чем-то отдельным от java.
Если для вас все языки на jvm называются "java" то какой термин вы используете для обозначения самого языка java?
А это не следствие одно другого?
В некоторых языках со статической типизацией можно указывать типы гораздо меньше чем в java. А в питоне надо при каждом использовании полей объекта писать self.
sshikov
13.03.2019 13:55Это не я использую термин Java, это автор почему-то думает, что реальная разработка ведется только на Java, а в том же проекте котлин — ни-ни. Что в реальности немножко совсем не так, к примеру еще в дремучем 2009 я спокойно использовал Jython, при этом для парсинга XML ничего лучше чем JAXP (xalan) не нашел, и применил его. Ну то есть, понимаете — какой-то питон у меня тоже есть, ага (оставим пока вопрос, что он был 2.х)?
>В некоторых языках со статической типизацией можно указывать типы гораздо меньше чем в java.
Это щас было про var? ;) В смысле, еще меньше чем ничего?
sshikov
13.03.2019 13:59>какой термин вы используете
Я стараюсь не путать экосистему и язык. И пишу я под экосистему по большей части. И да, это иногда путает, когда именем языка обзывают экосистему.
tuxi
13.03.2019 13:41Например, динамической типизации?
Равно как и то и другое может играть эту роль. Если задаться целью, то можно провести исследование и выяснить это более точно
Например, переведите это на джаву:
я только в общих чертах представляю себе scala, но насколько понимаю, речь идет про «сравнение по содержимому», другими словами есть некий метод, который использует аргументы конструктора, чтобы построить некий hash и сравнить по нему. Если бы такое потребовалось бы, то я бы реализовал бы нужные hashCode, equals и тп и сравнивал бы, хоть по образцу, хоть динамически возникшие инстансы. Вы же не думаете, что это автоматом +50% к коду по всему проекту?
sshikov
13.03.2019 13:56На самом деле ломбок. Я его не очень люблю, но именно эту проблему он решит с полпинка.
nexus478
13.03.2019 20:43А кто-нибудь может сказать, зачем использовать питон на бэкенде в 2019 году? Вопрос без подвоха, не вижу ни одного конкурентного преимущества перед Go или Node.js. Фреймворки развиваются вяло, язык развивается вяло. Недаром постоянно слышу, как очередной питонист перешел на го. Какие бенефиты могут быть от выбора питона?
sshikov
14.03.2019 20:52Ну, по большому счету затем же, зачем и любой другой язык. Если у вас есть опыт питона, и нет Node.js — то почему нет? Этот опыт и будет конкурентным преимуществом питона для вас. Сегодня. Через пять лет — возможно все поменяется.
exerrk
Интересно, как часто это используется? Мне не приходилось менять местами значение переменных, что со мной не так?
shiru8bit
Сильно сомневаюсь, что где-либо это нужно часто, а так — вчера приходилось, сортировка цветов в палитре по яркости с некоторыми условиями (скорость неважна, сгодился простейший bubble sort). И если подумать, кроме задач ручной кастомной сортировки ничего в голову и не приходит.
Dim0v
Ну чесно говоря, причин писать сортировку руками я тоже особо придумать не могу. Параметров
key
иcmp
вполне достаточно для описания любой сортировки.Разве что это какие-то экзотические ситуации, типа данных, не влезающих в память и требующих сортировки слиянием или каких-то специфических данных, требующих сортировки без сравнений (подсчетом/поразрядной). Но мне кажется, для большинства таких ситуаций python все равно не тот язык, который будет использоваться.
fireSparrow
Это частный случай присваивания с распаковкой.
Чаще приходится делать что-то такое:
Но и в приведённом виде тоже приходится использовать, хотя чаще не с отдельными переменными, а с элементами списка:
sergey-gornostaev
Удобная возможность. Например в Twisted часто применяется такой способ освобождения ссылки на Defered
roscomtheend
RGB <-> BGR