Миграция с CPython на Jython - PullRequest
       40

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

24 голосов
/ 07 января 2009

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

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

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

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

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

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

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

Ответы [ 6 ]

10 голосов
/ 05 апреля 2010

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

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

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

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

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

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

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

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

8 голосов
/ 07 января 2009

Пока что я заметил еще две проблемы:

  • Строковое интернирование '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 была бы простой, и я уверен, что они примут патчи.

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

5 голосов
/ 19 декабря 2010

Я начинаю это как вики, собранную из других ответов и моего опыта. Не стесняйтесь редактировать и добавлять материал, но, пожалуйста, старайтесь придерживаться практических советов, а не списка сломанных вещей. Вот старый список отличий от сайта 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

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

Пропавшие вещи

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

Performance

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

Пользователи

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

3 голосов
/ 05 апреля 2010

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

3 голосов
/ 11 мая 2009

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

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

2 голосов
/ 17 декабря 2010

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

Когда я впервые запустил программу с Jython, она сразу вылетела. С одной стороны, «.fieldnames» csv.reader всегда казался None. Поэтому мне пришлось изменить несколько частей нашего кода, чтобы обойти это.

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

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

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

...