Взаимодействие интерпретаторов Python-IronPython-Jython

    Возникла необходимость в решении такой задачи: как обмениваться данными между разными интерпретаторами Python?! Отыскал несколько решений, но хочу рассказать об одном, на мой взгляд, самом удобном.

    Выбор подхода


    Для начала я пытался выбрать наиболее удобное решение из множества. Может не корректно сравнивать message queue, сокеты и RPC, но я исходил от задачи. Вот что доступно:

    Сокеты TCP

    Использование сокетов, наиболее простой способ взаимодействия, можно передавать любые данные, но код придётся насыщать реализацией собственного протокола. Этот путь тернист, и ошибки неизбежны. Вывод: подходит, но сложно.

    Библиотека ZeroMQ

    Очень перспективная разработка brokerless очередь сообщений. Реализована как библиотека pyzmq и pyzmq-static. Для первого случая нужно установить саму ZeroMQ — написанная на C разделяемая библиотека. Вторая уже содержит бинарник. Начиналось всё весьма забавно, код работал отлично, пока я не перешёл к IronPython…
    Для IronPython pyzmq не реализована, но не проблема, есть же .NET Integration, что позволяет использовать clrzmq — биндинг для .NET; и вот здесь начались проблемы. Бинарник доступен через плагин для VisualStudio — nuget, поэтому пришлось бибилотеку компилировать.Скачал исходник, там всё удобно, скрипт собирается командой build, но не всё так просто. Версия 2 не собралась вообще, хотя зависимости разрешила через nuget корректно (может взял битый commit?), 3 бета собралась, но падала даже на примере из tutorial )
    В итоге и сети отыскал бинарник 2-ки, но это меня совсем не порадовало. Всё заработало, но API в 3-ке так сильно изменился, что не хотелось потом переписывать код по сто раз. Вывод: хорошо, но сыро вне чистого Python.

    Pyro, поджигай!

    Поначалу решил добивать 0mq, но вспомнил о сущеcтвовании такой библиотеки как Pyro: библиотеки из кризисных 90-х, которая прекрасно поживает и развивается. Не буду перечислять все её плюсы, сейчас интересует только один — взаимодействие интерпретаторов. Сразу к делу, пробуем пример из tutorial, но с той разницей, что запускаем всё под разными интерпретаторами (код не менял, только вписал свой ник).

    Запускаем сервер имён под Jython, кстати, вот и первый огромный плюс, у 0mq сервер имён ещё не доделан:

    Ого! Завелось...

    Теперь регистрируем сервер, который будет работать под IronPython:

    Регистрация прошла успешно.

    Следующий шаг, запуск клиента. Делаем под классическим питоном (у меня их сразу много стоит, но запускал EPD):

    Прекрасно! Всё сработало.

    Версия pickle

    Как вариант, попробовал ещё запускать одну из частей под Python 3. Без хака не сработало :( Последний использует pickle третьей версии + нет некоторых стандартных модулей (удалены, перенесены), хотя это поведение можно обойти. Но главная причина, Pyro4 иcпользует pickle для сериализации, при этом самую последнюю версию. Вот как удалось обойти этот недостаток и подключиться Python 3 к IronPython 2 и Jython 2:
    import pickle
    pickle.HIGHEST_PROTOCOL = 2
    

    Это нужно добавить в код клиента перед импортом Pyro. Всё сработало:

    Обратите внимание на использование 64-битного Python 3 вместе с двойками.

    Кстати, как вариант, можно использовать библиотеку pyrolite для прямого подключения из .NET или Java без Python интерпретатора. Это фактически мини pickle.

    В целом решение с Pyro пока понравилось больше других, если же система содержит очень много компонент разных версий, то, наверное, выгоднее будет использовать 0mq. Хотя я пока остановлюсь всё же на Pyro4.
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 11

      0
      Оффтопик: а что за приложение, в котором вы iPython Запускаете? Какая-то продвинутая консоль?
        0
        похоже на Console2, так как такую же себе недавно установил
          0
          Всё верно, даю ссылку, это Console2, очень приятная консоль. (Даже прозрачность поддерживает, но отключил для статьи =)

          Удобно, что можно много типов вкладок зашить: под все питоны и шеллы. И запускать в одном окне, когда требуется.
            +1
            А про ConEmu слышали? Попробуйте ;)
              0
              Не слышал. Спасибо за ссылку!
                0
                Спасибо! Тоже первый раз слышу. Буду пробовать.
                  0
                  А можно стандартную виндовую консоль заменить этой и забыть про проблемы с кодировками при разработке консольного софта под вин?
                    0
                    Не очень понял, что значит «заменить»? Либо используете ConEmu, либо нет.

                    И какие конкретно проблемы беспокоят?
                      0
                      Значит чтобы вывод консольных приложений шел не в стандартную убогую консоль, а в сабж.

                      Что касается проблем… в стандартной консоли винды используется кодировка 866. Хотелось бы UTF-8.
                        0
                        Эм. Не вижу проблемы запустить консольное приложение в сабже.

                        Что до UTF-8, то консоль как бы по умолчанию юникодная, начиная с NT. Так что мне не совсем понятно, при чем тут UTF-8, если приложение не умеет «печатать» в юникоде. Другими словами, если оно зовет printf используя однобайтовую кодировку — юникодным ее вывод не будет. Но отображается-то он правильно.

                        Вобщем-то любые реальные (и четко сформулированные) фичреквесты приветствуются на сайте программы.
                0
                Огромное спасибо за статью

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                Самое читаемое