Python: использование модулей, которые поддерживают разные версии Python в одном проекте - PullRequest
0 голосов
/ 06 мая 2018

У меня есть 2 модуля Python, где один поддерживает только Python 2.x, а другой 3.x. К сожалению, мне нужны оба проекта. Мой обходной путь на данный момент заключается в том, чтобы они запускались сами по себе в качестве отдельных программ и создавали связь через модуль сокетов.

  1. Я получу 2 исполняемых файла, чего я бы хотел избежать.
  2. «Соединение» между обоими модулями должно быть максимально быстрым.

Так что мой вопрос: есть ли способ как-то объединить оба в один исполняемый файл в конце, и если есть лучшее решение для быстрой связи, как у меня сейчас клиент-серверная конструкция.

1 Ответ

0 голосов
/ 06 мая 2018

Нет действительно хорошего способа избежать этого обходного пути.

Концептуально, нет причин, по которым вы не могли бы встроить двух переводчиков в один процесс. Но практически интерпретатор CPython зависит от некоторого статического / глобального состояния. Хотя 3.7 намного лучше, чем, скажем, 3.0 или 2.6, это состояние еще почти не устранено. 1 И, как работает связь С, нет способа обойти это без изменения переводчик.

Кроме того, встраивание CPython не является сложным , но это не тривиально , в том смысле, что запуск интерпретатора в качестве подпроцесса тривиален - и это может быть сложнее, чем придумать с эффективным способом передачи или совместного использования состояния между подпроцессами.

Конечно, есть и другие переводчики, кроме CPython. Но другая основная реализация с версиями 2.7 и 3.x не может быть легко встраиваемой (PyPy), а две легко внедряемые не имеют версий 3.x, а также могут быть встроены только в другую виртуальную машину и могут не использовать модули расширения C (Jython и IronPython). можно сделать что-то вроде использования JEP для встраивания CPython 3.7 через JNI в JVM, а также использовать Jython 2.7 изначально в той же JVM, но я сомневаюсь, что этот подход будет работать для вас.

Между тем, я упоминал, что передача или обмен данными между процессами обычно не так сложен.

  • Если у вас не так много данных, вы можете просто пропустить их через трубу.
  • Если у вас есть тонна данных, они обычно хранятся или могут быть сохранены в памяти в какой-либо структурированной форме - массивы, большие фрагменты текста ASCII или UTF-8, массивы структур ctypes и т. Д. - что вы можете наложить на mmap или сегмент общей памяти.
  • Или, конечно, вы можете придумать свой собственный протокол и обмениваться данными с ним через (UNIX или IP) сокет. Но вам не обязательно прыгать прямо к этой опции.

Обратите внимание, что multiprocessing поддерживает оба первых двух, хотя, чтобы воспользоваться преимуществами независимых переводчиков, вам нужно покопаться в его источнике и извлечь нужные биты. И есть сторонние библиотеки, которые могут помочь. (Например, если вам нужно перебирать вещи, которые не перебираются изначально, ответ часто так же прост, как «заменить pickle на dill».)


1. Запуск нескольких субинтерпретаторов различными способами ограниченно работает с такими вещами, как mod_wsgi, а PEP 554 направлен на то, чтобы привести вас в состояние, когда вы можете легко и безошибочно запускать несколько субинтерпретаторов 3.7 в одном процессе, но все еще ничего похожего на полностью независимые вложения CPython - субинтерпретаторы имеют общий GIL, сборщик циклов, обработчик atexit и т. д.

...