понедельник, 22 ноября 2010 г.

Python vs C# vs Matlab

Недавно начал изучать Pyhon. Изучение идет очень легко и приятно. Я бы даже сказал, что это похоже на общение с человеком, с которым ты во многом согласен. По ходу чтения постоянно возникают мысли "Да! Именно так и должно быть. Здорово!".
В принципе изучение основ заняло несколько часов, язык очень интуитивно понятен и логичен.
Но вот дело подошло к разработке реальной программы и начали возникать сравнения с теми языками на которых я раньше писал то же самое.
Итак, плюсы питона:
  • Поддержка кортежей, списков и словарей на уровне языка - круто!
  • duck typing - поначалу трудно перестроить свой мозг на такую концепцию, но это обещает быть полезным.
  • Простота и прямота синтаксиса.
  • Динамическая типизация.
  • Итераторы.
  • Бесплатный, платформонезависимый.
  • Очень многие вакансии в области Computer vision требуют знание питона.

А теперь, что не понравилось или что я пока не понял:
  • Отсутствие приватных членов класса. Жуть. Все члены публичные? А для обозначения приватности используется _? У меня имеется какая-то личная неприязнь к подчеркиванию в коде. Всегда предпочитал camel, pascal или hungarian notation, а код с большим количеством _ мне казался грязным. Уж не знаю как так получилось.
  • Отсутствие необходимости явного объявления полей класса это конечно плюс, но есть в этом и минус.

Вот пример объявления класса на c#:
class Layer
{
float[][] weights;
float[] biases;
bool isCuda;
public float[] Propagate(float[] inputs)
{
if(isCuda)
return CuPropagate(inputs);
else
return dot(inputs, weights) + biases;
}
private float[] CuPropagate(float[] inputs)
{
//...
}
}

* This source code was highlighted with Source Code Highlighter.
и то же на Python:
class layer:
propagate(
self, inputs)
if self.isCuda :
return self._cuPropagate(inputs)
else:
return dot(inputs, weights) + biases;

_cuPropagate(inputs):
//...

Выглядит более компактно , нет скобок - это плюс, правда везде нужно писать self - напрягает. Но! Пример на C# обладает преймуществами декларативного стиля. Из объявления класса мне понятно, что weights - это матрица float'ов, biases - вектор, что есть флаг isCuda. Прочитав только эти первые строки объявления класса и не видя имплементации мне уже почти все о классе понятно. Кроме того я не смогу вызвать по ошибке CuPropagate и обрушить программу, в случае если cuda непроинициализирована, поскольку метод приватный.
И еще момент. Если я попытаюсь в качестве inputs скормить double[], С ругнется еще на этапе компиляции, тогда как в питоне все нормально скомпилируется, а обнаружится уже тогда, когда видеокарта ругнется и скажет, что double не поддерживается.
  • Отсутствие продвинутой IDE. В C# я могу себе позволить называть функции длинными, осмысленными именами, поскольку знаю, что набирать потом буду всего 3-4 первых символа, дальше подскажет IntelliSence. В последних версиях VS intellisence очень крут. Если я пишу несколько строк подряд в таком виде:

this.visSettingsWindow.RefineButton.Click += new EventHandler(RefineButton_Click);
this.visSettingsWindow.UndoRefineButton.Click += new EventHandler(UndoRefineButton_Click);
this.visSettingsWindow.BorderBlocksButton.Click += new EventHandler(BorderBlocksButton_Click);
this.visSettingsWindow.OcclBorderButton.Click += new EventHandler(OcclBorderButton_Click);

* This source code was highlighted with Source Code Highlighter.
то я набираю th.vi.cl+="Tab""Tab"; следующую строку я уже набираю как th..un.+="Tab""Tab"
При этом я вижу описание каждого члена, данных, которые он хочет на входе и т.п.
Похожего удобства для питона я не знаю. Пробовал pydev для eclipse. Он конечно подсказывает, но крайне мало. Все приходится держать в голове.
  • По поводу консоли питона. Хотелось бы, что бы она была больше похожа на matlab консоль. Т.е. если я ввожу переменную a = rand(10, 5), у меня где-нибудь на панели отображалась информация об этой переменной, чтоб я не держал ее в голове. И еще история введенных команд где-нибудь в стороне.
  • Пока не понял как в питоне реализовать механизм аналогичный делегатам
  • Отсутствие чего-то похожего на LINQ. Бывало, что одна строчка на linq заменяет метод на несколько страниц.
  • Непонятно, можно ли делать вставки в критических по скорости местах на с++, по типу unsafe { } или что-то аналогичное
Хочу подчеркнуть, что это никоим образом не является наездом на питон. Он мне очень нравится, и я буду благодарен, если опытные питонисты мне укажут где я был не прав, или каких важных преимуществ питона не учел.

7 комментариев:

kkirsanov комментирует...

--Отсутствие продвинутой IDE. В C# я могу себе позволить называть функции длинными, осмысленными именами, поскольку знаю.

Eclipse+Pydev - http://pydev.org/

--Пока не понял как в питоне реализовать механизм аналогичный делегатам


При наличии функций высших порядков это не нужно. Просто передаете функцию как аргумент.


--Отсутствие чего-то похожего на LINQ. Бывало, что одна строчка на linq заменяет метод на несколько страниц.

map, reduce, filter, lambda, for и списковых выражений как правило хватает:

listOfTags = list(set(reduce(lambda x,y:x+y, [p.tags for p in filter (lambda p:(p.key() in self.partner.projects) or (p.userAccess) , projects)))))


--Непонятно, можно ли делать вставки в критических по скорости местах на с++, по типу unsafe { } или что-то аналогично


Можно, но не очень удобно

http://kkirsanov.livejournal.com/334650.html


Вот сравнение эффективности различных решений - http://www.scipy.org/PerformancePython


--По поводу консоли питона. Хотелось бы, что бы она была больше похожа на matlab консоль. <...>И еще история введенных команд где-нибудь в стороне.


Я перепробовал множество python-консолей, остановился на ipython

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

kkirsanov комментирует...

PS: касательно матлаба, - крайне рекомендую http://scipy.org/

Unknown комментирует...

2kkirsanov: Спасибо. Особенно за пример с аналогом LINQ.
Pydev я кстати сразу поставил, но как я написал он не так много показывает. Хотя может это следствие особенностей языка. Т.к. если в методе описываешь вызов члена объекта переданного в качестве параметра, то без статической типизации нельзя узнать какие там есть методы и все их отобразить до компиляции.
scypy и numpy поставил. Там у них в доках даже таблица соответствий есть между функциями матлаба и scipy. Жаль только что питон 3 они не поддерживают и непонятно когда начнут.

Vladislav Gubarev комментирует...

По поводу приватных полей: можно использовать два подчеркивания перед названием члена класса (например __spam). В этом случае доступ снаружи все равно будет, но не по исходному навзанию члена, а с префиском (_classname__spam). Источник.

На мой взгляд стиль кодирования, принятый в питоне, самый приятный и легко читаемый. Советую почитать PEP8. Есть много скриптов по проверке стиля кодирования на Python. Я использую pylint (есть в пакетах Ubuntu).

В качестве IDE перепробовал много всего, но лучше Vim не нашел. Пробовал перейти на Eclipse несколько раз, но больше 2 дней не выдерживал. К vim можно прикрутить всякие полезные штуки типа умного автодополнения, проверку на соответсвие PEP8 и т.п.

Unknown комментирует...

2Vlad: Спасибо, полезные ссылки

Vladislav Gubarev комментирует...

Кажется вставки C++ можно делать с помощью Weave.

У меня есть положительные опыт использования Boost Python, но это уже не просто вставки, а создание библиотеки на C++, совместимую с Python.

AKrapov комментирует...

А смысл изучать питон, если до того учили C#?

Это же шаг назад. И нет таких программ которые на питоне были бы реализованы красивее. Хотя бы потому что на шарпе есть динамическая компиляция в DLL файлы, и потом добавили Iron Python.
И потом учить ещё 1 язык и целую кучу подводных камней... Достоинство одного языка как раз в том что не надо преодолевать весь путь. Спокойно пишешь COM объекты, ASP.NET ВЕБ сайты, службы для Windows.