Я подумываю о переносе моего кода (около 30K LOC) с CPython на Jython, чтобы я мог лучше интегрироваться с моим Java-кодом.
Есть ли контрольный список или руководство, на которое я должен обратить внимание, чтобы помочь мне с миграцией? Есть ли у кого-нибудь опыт делать что-то подобное?
После прочтения Сайт Jython большинство проблем кажутся слишком неясными, чтобы меня беспокоить.
Я заметил, что:
Что-нибудь еще?
Связанный вопрос: Каковы стратегии написания кода Python, работающего в CPython, Jython и IronPython?






Пока что я заметил еще две проблемы:
Jython 2.5b0 (trunk:5540, Oct 31 2008, 13:55:41)
>>> 'a' is 'a'
True
>>> s = 'a'
>>> 'a' is s
False
>>> 'a' == s
True
>>> intern('a') is intern(s)
True
Вот тот же сеанс на CPython:
Python 2.5.2 (r252:60911, Oct 5 2008, 19:24:49)
>>> 'a' is 'a'
True
>>> s = 'a'
>>> 'a' is s
True
>>> 'a' == s
True
>>> intern('a') is intern(s)
True
(Я делал то же самое, что и вы, недавно портировал приложение)
о да, в этом вы правы. Но не забывайте про «is None» / «is not None», это немного отличается от случая «is-same-object», который вы описываете, это больше похоже на «is-null» (я думаю).
@shylent: "None" (т.е. null на других языках) является одноэлементным (источник: docs.python.org/c-api/none.html)
Когда я некоторое время назад переключил проект с CPython на Jython, я понял, что для критичных по времени секций скорость снижена до 50 раз. Из-за этого я остался с CPython.
Однако это могло измениться сейчас с текущими версиями.
Говоря в 2015 году, я бы сказал, что это все еще проблема. И выполнение, и запуск Jython болезненны. Но против этого вы должны противопоставить яркость идеи Jython. Есть (очевидные) стратегии: писать критичные ко времени вещи прямо на Java, использовать CPython для начального запуска и тестировать новые биты, не связанные с какими-либо классами Java. Священным Граалем, по-видимому, является беспроблемная интеграция CPython-Jython ...
Прежде всего, я должен сказать, что реализация Jython очень хороша. Большинство вещей «просто работает».
Вот несколько вещей, с которыми я столкнулся:
Модули C, конечно, недоступны.
open ('file'). read () не закрывает файл автоматически. Это связано с разницей в сборщике мусора. Это может вызвать проблемы со слишком большим количеством открытых файлов. Лучше использовать идиому «with open ('file') as fp».
Установка текущего рабочего каталога (с помощью os.setcwd ()) работает для кода Python, но не для кода Java. Он эмулирует текущий рабочий каталог для всего, что связано с файлами, но может делать это только для Jython.
Синтаксический анализ XML попытается проверить внешний DTD, если он доступен. Это может вызвать значительное замедление кода обработки XML, поскольку синтаксический анализатор будет загружать DTD по сети. У меня сообщил об этой проблеме, но пока не исправлено.
Метод __ del __ вызывается в коде Jython очень поздно, а не сразу после удаления последней ссылки на объект.
Есть старый список отличий, но недавний список недоступен.
О методе __del__: спецификация на самом деле не определяет, когда именно метод должен быть вызван, поэтому вам вообще не следует полагаться на него в своем коде. (Я считаю, что где-то в документации Python есть уведомление об этом.)
Вы также можете изучить JPype. Я не уверен, насколько он зрелый по сравнению с Jython, но он должен позволить CPython получать доступ к Java-коду.
Недавно я работал над проектом для профессора в моей школе с группой. Вначале было решено, что мы будем писать проект на Python. Нам определенно стоило использовать CPython. Мы написали программу на Python, и все наши модульные тесты в итоге заработали. Поскольку у большинства людей на компьютерах уже установлена Java, а не Python, мы решили просто развернуть ее как Jython jar. Поэтому мы написали графический интерфейс с помощью Swing, потому что он включен в стандартную библиотеку Java.
Когда я впервые запустил программу с Jython, она сразу же вылетела. Во-первых, csv.reader's ".fieldnames" всегда казался None. Поэтому мне пришлось изменить несколько частей нашего кода, чтобы обойти это.
Также произошел сбой в другом разделе моего кода, который отлично работал с CPython. Jython обвинил меня в том, что я ссылаюсь на переменную до того, как ей что-либо было присвоено (что сводило меня с ума, но на самом деле это не так). Это один из примеров: Внешняя сортировка рецепта кода ActiveState
Что еще хуже, спектакль был ужасным. В основном этот код объединял несколько файлов CSV, один из которых был около 2 ГБ. В CPython он работал за 8,5 минут. В Jython он работал за 25 минут.
Эти проблемы произошли с 2.5.2rc2 (последней на момент написания этого поста).
Я начинаю это как вики, собранную из других ответов и моего опыта. Не стесняйтесь редактировать и добавлять материалы, но, пожалуйста, старайтесь придерживаться практических советов, а не списка сломанных вещей. Вот старый список отличий с сайта Jython.
Jython не использует подсчет ссылок, поэтому ресурсы высвобождаются по мере их использования. собираются мусором, что намного позже, чем вы увидите в эквиваленте Программа CPython
open('file').read() не закрывает файл автоматически.
Лучше используйте идиому with open('file') as fp.mysqldb - это модуль c, поэтому он не будет работать в jython. Вместо этого вы
следует использовать com.ziclix.python.sql.zxJDBC, который идет в комплекте с Jython.
Замените следующий код MySQLdb:
connection = MySQLdb.connect(host, user, passwd, db, use_unicode=True, chatset='utf8')
С участием:
url = "jdbc:mysql://%s/%s?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull" % (host, db)
connections = zxJDBC.connect(url, user, passwd, "com.mysql.jdbc.Driver")
Вам также необходимо заменить все _mysql_exception на zxJDBC.
Наконец, вам нужно заменить заполнители запросов с %s на ?.
unichr(0xd800) вызовет исключение, а наличие буквального u'\ud800'
в вашем коде просто нанесет ущерб.Проект Jython все еще жив, но не так быстро развивается. В список рассылки разработчиков имеет около 20 сообщений в месяц, и кажется, что разработчиков всего около 2 совершающий код в последнее время.
Как я знаю, "is" нужно использовать только для проверки, хранятся ли объекты в одном и том же месте в памяти. Использование «is» вместо «==» - плохая привычка.