Вызываете Python на Java? - PullRequest
       18

Вызываете Python на Java?

99 голосов
/ 17 января 2012

Мне интересно, возможно ли вызывать функции Python из кода Java с использованием jython или это только для вызова кода Java из Python?

Ответы [ 9 ]

89 голосов
/ 17 января 2012

Jython: Python для платформы Java - http://www.jython.org/index.html

Вы можете легко вызывать функции Python из кода Java с помощью Jython. То есть, если ваш код на Python работает под jython, то есть не использует некоторые c-расширения, которые не поддерживаются.

Если это работает для вас, это, безусловно, самое простое решение, которое вы можете получить. В противном случае вы можете использовать org.python.util.PythonInterpreter из новой поддержки интерпретатора Java6.

Простой пример из головы - но должен работать, я надеюсь: (для краткости проверка ошибок не производится)

PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec("import sys\nsys.path.append('pathToModules if they are not there by default')\nimport yourModule");
// execute a function that takes a string and returns a string
PyObject someFunc = interpreter.get("funcName");
PyObject result = someFunc.__call__(new PyString("Test!"));
String realResult = (String) result.__tojava__(String.class);
54 голосов
/ 05 ноября 2014

Привет, я думал, что введу свой ответ на это, хотя уже поздно. Я думаю, что есть несколько важных вещей, которые нужно рассмотреть в первую очередь, насколько сильно вы хотите иметь связь между Java и Python.

Во-первых Вы хотите только вызывать функции или действительно хотите, чтобы код Python изменял данные в ваших Java-объектах? Это очень важно. Если вы хотите вызвать только некоторый код Python с аргументами или без них, то это не очень сложно. Если ваши аргументы являются примитивами, это делает это еще проще. Однако если вы хотите, чтобы java-класс реализовывал функции-члены в python, которые изменяют данные объекта java, то это не так просто или просто.

Во-вторых мы говорим на cpython или подойдет jython? Я бы сказал, что cpython это где! Я бы защищал это, почему питон такой крутой! Имея такие высокие абстракции, однако доступ к c, c ++ при необходимости. Представьте себе, если бы вы могли иметь это в Java. Этот вопрос даже не стоит задавать, если с jython все в порядке, потому что тогда все равно легко.

Итак, я играл со следующими методами и перечислил их от простого к сложному:

Java для Jython

Преимущества: Тривиально просто. Имеют фактические ссылки на объекты Java

Недостатки: Нет CPython, очень медленно!

Jython из java очень прост, и если этого действительно достаточно, то отлично. Однако это очень медленно и не cpython! Стоит ли жить без cpython, я так не думаю! Вы можете легко получить код Python, реализующий ваши функции-члены для ваших объектов Java.

Java с Jython на CPython через Pyro

Pyro - это модуль удаленного объекта для python. У вас есть некоторый объект в интерпретаторе cpython, и вы можете отправлять ему объекты, которые передаются через сериализацию, и он также может возвращать объекты с помощью этого метода. Обратите внимание: если вы отправляете сериализованный объект python из jython, а затем вызываете некоторые функции, которые изменяют данные в его членах, вы не увидите эти изменения в java. Вам просто нужно помнить, чтобы отправить обратно данные, которые вы хотите от пиро. Я считаю, что это самый простой способ попасть в cpython! Вам не нужны никакие jni, jna, swig или .... Вам не нужно знать ни c, ни c ++. Кул, да?

Преимущества: Доступ к cpython, не такой сложный, как следующие методы

Недостатки: Невозможно изменить данные об элементах java-объектов напрямую из python. Несколько косвенно, (jython - средний человек).

Java на C / C ++ через JNI / JNA / SWIG на Python через встроенный интерпретатор (возможно, с использованием библиотек BOOST?)

О Боже, этот метод не для слабонервных. И я могу сказать вам, что мне понадобилось очень много времени, чтобы добиться этого приличным методом. Основная причина, по которой вы захотите это сделать, заключается в том, что вы можете запускать код cpython, который полностью контролирует ваш Java-объект. Перед тем, как попробовать попробовать java (которая похожа на шимпанзе) с python (которая похожа на лошадь), необходимо учесть основные важные моменты. Во-первых, если вы выйдете из строя, переводчик отключит вашу программу! И не заводите меня на проблемы параллелизма! Кроме того, есть много отведенного котла, я считаю, что я нашел лучшую конфигурацию для минимизации этого котла, но все же он отведен! Итак, как это сделать: Учтите, что C ++ - ваш посредник, ваши объекты на самом деле являются объектами C ++! Хорошо, что ты это знаешь сейчас. Просто напишите ваш объект, как будто ваша программа, как в cpp, а не в java, с данными, к которым вы хотите получить доступ из обоих миров. Затем вы можете использовать генератор-обертку с именем swig (http://www.swig.org/Doc1.3/Java.html), чтобы сделать это доступным для java, и скомпилировать dll, который вы называете System.load (имя dll здесь) в java. Сначала запустите это, затем перейдите к сложная часть!Чтобы попасть на python, вам нужно встроить интерпретатор.Во-первых, я предлагаю сделать несколько программ-интерпретаторов hello или этот урок Встраивание python в C / C .Как только у вас все получится, самое время заставить лошадь и обезьяну танцевать!Вы можете отправить свой объект c ++ в python через [boost] [3].Я знаю, что я не дал вам рыбу, просто сказал вам, где найти рыбу.Некоторые указания, на которые следует обратить внимание при компиляции.

Когда вы компилируете boost, вам нужно будет скомпилировать общую библиотеку.И вам нужно включить и ссылаться на то, что вам нужно из jdk, т.е. jawt.lib, jvm.lib, (вам также понадобится клиент jvm.dll на вашем пути при запуске приложения), а также python27.lib иличто угодно и boost_python-vc100-mt-1_55.lib.Затем включите Python / include, jdk / include, boost и используйте только общие библиотеки (dll), в противном случае boost имеет слезоточивый характер.И да, в полной мере я знаю.Есть так много способов, которыми это может испортиться.Поэтому убедитесь, что вы делаете каждую вещь блок за блоком.Тогда соедините их.

9 голосов
/ 16 марта 2017

В некоторых ответах упоминается, что вы можете использовать JNI или JNA для доступа к cpython, но я бы не рекомендовал начинать с нуля, поскольку уже есть библиотеки с открытым исходным кодом для доступа к cpython из java.Например:

9 голосов
/ 26 февраля 2017

Не разумно иметь код Python внутри Java.Оберните ваш код Python флягой или другим веб-фреймворком, чтобы сделать его микросервисом.Сделайте так, чтобы ваша java-программа могла вызывать этот микросервис (например, через REST).

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

7 голосов
/ 10 июня 2017

Вот библиотека, которая позволяет вам написать свои скрипты Python один раз и решить, какой метод интеграции (Jython, CPython / PyPy через Jep и Py4j) использовать во время выполнения:

https://github.com/subes/invesdwin-context-python

Поскольку каждый метод имеет свои преимущества / недостатки, как описано в ссылке.

4 голосов
/ 06 декабря 2012

В зависимости от ваших требований могут быть полезны такие опции, как XML-RPC , которые можно использовать для удаленного вызова функций практически на любом языке, поддерживающем протокол.

4 голосов
/ 17 января 2012

Это зависит от того, что вы подразумеваете под функциями python?если они были написаны на cpython , вы не можете напрямую вызывать их, вам придется использовать JNI , но если они были написаны на Jython , вы можете легко вызвать их изjava, так как jython в конечном итоге генерирует Java-байт-код.

Теперь, когда я говорю «написано на cpython или jython», это не имеет особого смысла, потому что python - это python, и большая часть кода будет работать в обеих реализациях, если вы не используете специальные библиотеки.который опирается на cpython или java.

см. здесь как использовать интерпретатор Python в Java.

3 голосов
/ 17 января 2012

Вы можете вызывать любой язык из Java, используя Собственный интерфейс Java

2 голосов
/ 06 октября 2015

Jython имеет некоторые ограничения:

Есть ряд отличий. Во-первых, программы Jython не могут использовать CPython модули расширения, написанные на C. Эти модули обычно имеют файлы с расширение .so, .pyd или .dll. Если вы хотите использовать такой модуль, вы должны посмотреть для эквивалента, написанного на чистом Python или Java. Хотя это технически возможна поддержка таких расширений - IronPython делает так - планов нет сделать это в Jython.

Распространение моих скриптов Python в виде файлов JAR с Jython?

Вы можете просто вызывать скрипты Python (или скрипты bash или Perl) из Java с помощью Runtime или ProcessBuilder и передавать результат обратно в Java:

Запуск сценария оболочки bash в java

Запуск командной строки в Java

java runtime.getruntime (), получающий вывод от выполнения программы командной строки

...