Подтвердить что ты не робот

Миграция с CPython на Jython

Я подумываю о переносе моего кода (около 30K LOC) с CPython на Jython, чтобы я мог лучше интегрироваться с моим java-кодом.

Есть ли контрольный список или руководство, на которое я должен обратить внимание, чтобы помочь мне с миграцией? Кто-нибудь имеет опыт работы с чем-то похожим?

Из чтения сайта Jython, большинство проблем кажутся слишком неясными, чтобы беспокоить меня.

Я заметил, что:

  • безопасность потоков - проблема.
  • Поддержка Unicode кажется совсем другой, что может быть проблемой для меня.
  • mysqldb не работает и нуждается в замене на zxJDBC

Что-нибудь еще?

Связанный вопрос: Каковы некоторые стратегии для написания кода Python, который работает в CPython, Jython и IronPython

4b9b3361

Ответ 1

Я начинаю это как вики, собранную из других ответов и моего опыта. Не стесняйтесь редактировать и добавлять материал, но, пожалуйста, старайтесь придерживаться практических советов, а не списка сломанных вещей. Здесь старый список различий с сайта Jython.

Управление ресурсами

Jython не использует подсчет ссылок, и поэтому ресурсы освобождаются, поскольку они собираются мусор, что намного позже, чем вы увидите в эквиваленте Программа CPython

  • open('file').read() не закрывает файл автоматически. Лучше используйте идиому with open('file') as fp.
  • Метод __ del __ вызывается очень поздно в коде Jython, а не сразу после удаления последней ссылки на объект.

Интеграция MySQL

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 на ?.

Unicode

  • Вы не можете выражать незаконные символы Unicode в Jython. Попытка например unichr(0xd800) приведет к исключению и имеет литерал u'\ud800' в вашем коде просто навредит.

Отсутствующие вещи

  • Модули C недоступны, конечно.
  • os.spawn * функции не реализованы. Вместо этого используйте subprocess.call.

Производительность

  • Для большинства рабочих нагрузок Jython будет намного медленнее, чем CPython. Отчеты что-то от 3 до 50 раз медленнее.

Основной

Проект Jython все еще жив, но не работает быстро. список рассылки dev имеет около 20 сообщений в месяц, и, похоже, всего около 2 разработчиков комментируя код в последнее время.

Ответ 2

Во-первых, я должен сказать, что реализация Jython очень хороша. Большинство вещей "просто работают".

Вот несколько вещей, с которыми я столкнулся:

  • Модули C не доступны, конечно.

  • open ('файл'). read() не закрывает файл автоматически. Это связано с различием в сборщике мусора. Это может вызвать проблемы со слишком большим количеством открытых файлов. Лучше использовать "с открытым (" файлом ") как идиомой fp.

  • Установка текущего рабочего каталога (с использованием os.setcwd()) работает для кода Python, но не для кода Java. Он эмулирует текущий рабочий каталог для всех связанных с файлами, но может делать это только для Jython.

  • Разбор XML будет пытаться проверить внешний DTD, если он доступен. Это может привести к значительным замедлениям обработки кода обработки XML, поскольку парсер будет загружать DTD по сети. я сообщила об этой проблеме, но пока остается незафиксированной.

  • Метод __ del __ вызывается очень поздно в коде Jython, а не сразу после удаления последней ссылки на объект.

Существует старый старый список различий, но последний список недоступен.

Ответ 3

До сих пор я заметил еще две проблемы:

  • Строка интернирования 'a' is 'a' не гарантируется (и это всего лишь случайная реализация на CPython). Это может быть серьезной проблемой и действительно было в одной из библиотек, которые я переносил (Jinja2). Единичные тесты (как всегда) - ваши лучшие друзья!
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

  • os.spawn * функции не реализованы. Вместо этого используйте subprocess.call. Я был очень удивлен, так как реализация с использованием subprocess.call была бы простой, и я уверен, что они будут принимать патчи.

(Я делал то же, что и вы, перенося приложение недавно)

Ответ 4

Когда я переключил проект с CPython на Jython некоторое время назад, я понял скорость до 50x для критически важных секций. Из-за этого я остался с CPython.

Однако теперь это может измениться с текущими версиями.

Ответ 5

Вы также можете исследовать JPype. Я не уверен, насколько зрелым он сравнивается с Jython, но он должен позволить CPython получать доступ к Java-коду.

Ответ 6

Недавно я работал над проектом для профессора в моей школе с группой. Раньше было решено, что мы напишем проект в Python. Мы определенно должны были использовать CPython. Мы написали программу на Python, и все наши модульные тесты в конечном итоге сработали. Поскольку у большинства людей уже установлена ​​Java на своих компьютерах, а не на Python, мы решили просто развернуть ее как банку Jython. Поэтому мы написали GUI с Swing, потому что это включено в стандартную библиотеку Java.

В первый раз, когда я запускал программу с Jython, она сразу же разбилась. Во-первых, csv.reader ".fieldnames" всегда казался None. Поэтому мне пришлось изменить несколько частей нашего кода, чтобы обойти это.

Также разбился другой раздел моего кода, который отлично работал с CPython. Jython обвинил меня в ссылке на переменную, прежде чем ей было назначено что-либо (что заставило меня с ума сойти, и на самом деле это было не так). Это один из примеров: Внешний вид рецепта ActiveState Code

Хуже того, производительность была ужасная. В основном этот код объединил несколько файлов CSV, один из которых составлял около 2 ГБ. В CPython он работал через 8,5 минут. В Jython он работал через 25 минут.

Эти проблемы произошли с 2.5.2rc2 (последним на момент написания этого сообщения).