Using python library in java

Как вызвать Python Из Java

Изучите наиболее распространенные способы вызова кода Python из Java.

1. Обзор

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

В этом уроке мы рассмотрим некоторые из наиболее распространенных способов вызова кода Python из Java.

2. Простой Скрипт На Python

В этом уроке мы будем использовать очень простой скрипт на Python, который мы определим в специальном файле с именем hello.py :

print("Hello Baeldung Readers!!")

Предполагая, что у нас есть работающая установка Python, при запуске нашего скрипта мы должны увидеть напечатанное сообщение:

$ python hello.py Hello Baeldung Readers!!

3. Ядро Java

В этом разделе мы рассмотрим два различных варианта, которые мы можем использовать для вызова нашего скрипта Python с использованием ядра Java.

3.1. Использование ProcessBuilder

Давайте сначала рассмотрим, как мы можем использовать API ProcessBuilder для создания собственного процесса операционной системы для запуска python и выполнения нашего простого сценария:

@Test public void givenPythonScript_whenPythonProcessInvoked_thenSuccess() throws Exception < ProcessBuilder processBuilder = new ProcessBuilder("python", resolvePythonScriptPath("hello.py")); processBuilder.redirectErrorStream(true); Process process = processBuilder.start(); Listresults = readProcessOutput(process.getInputStream()); assertThat("Results should not be empty", results, is(not(empty()))); assertThat("Results should contain output of script: ", results, hasItem( containsString("Hello Baeldung Readers!!"))); int exitCode = process.waitFor(); assertEquals("No errors should be detected", 0, exitCode); >

В этом первом примере мы запускаем команду python с одним аргументом, который является абсолютным путем к вашему hello.py сценарий. Мы можем найти его в нашей папке test/resources .

Подводя итог, мы создаем наш объект ProcessBuilder , передавая значения команды и аргумента конструктору. Также важно упомянуть вызов redirectErrorStream(true). В случае каких-либо ошибок вывод ошибок будет объединен со стандартным выводом.

Это полезно, поскольку означает, что мы можем считывать любые сообщения об ошибках из соответствующего вывода при вызове метода getInputStream() для объекта Process . Если мы не установим этому свойству значение true , то нам нужно будет считывать выходные данные из двух отдельных потоков, используя методы getInputStream() и getErrorStream () .

Теперь мы запускаем процесс с помощью метода start () , чтобы получить объект Process . Затем мы читаем выходные данные процесса и проверяем, что содержимое соответствует нашим ожиданиям.

Как уже упоминалось ранее, мы сделали предположение, что питон команда доступна через ПУТЬ переменная.

3.2. Работа Со Скриптовым Движком JSR-223

JSR-223 , который был впервые представлен в Java 6, определяет набор API-интерфейсов сценариев, которые обеспечивают базовую функциональность сценариев. Эти методы предоставляют механизмы для выполнения сценариев и обмена значениями между Java и языком сценариев. Основная цель этого стандарта состояла в том, чтобы попытаться привнести некоторое единообразие во взаимодействие с различными языками сценариев из Java.

Мы можем использовать подключаемую архитектуру скриптового движка для любого динамического языка при условии, конечно, что он имеет реализацию JVM . Jython – это реализация платформы Java Python, которая работает на JVM.

Предполагая , что у нас есть Jython в CLASSPATH , фреймворк должен автоматически обнаружить, что у нас есть возможность использовать этот механизм сценариев, и позволить нам напрямую запросить механизм сценариев Python.

Поскольку Jython доступен из Maven Central , мы можем просто включить его в ваш pom.xml :

Аналогично, он также может быть загружен и установлен напрямую.

Давайте перечислим все скриптовые движки, которые у нас есть в наличии:

ScriptEngineManagerUtils.listEngines();

Если у нас есть возможность использовать Jython, мы должны увидеть соответствующий скриптовый движок:

. Engine name: jython Version: 2.7.2 Language: python Short Names: python jython

Теперь, когда мы знаем, что можем использовать скриптовый движок Jython, давайте продолжим и посмотрим, как вызвать hello.py скрипт:

@Test public void givenPythonScriptEngineIsAvailable_whenScriptInvoked_thenOutputDisplayed() throws Exception

Как мы видим, работать с этим API довольно просто. Во-первых, мы начнем с настройки ScriptContext , который содержит StringWriter . Это будет использоваться для хранения выходных данных скрипта, который мы хотим вызвать.

Затем мы используем метод getEngineByName класса ScriptEngineManager для поиска и создания скриптового движка для заданного короткого имени . В нашем случае мы можем передать python или jython , которые являются двумя короткими именами, связанными с этим движком.

Как и прежде, последний шаг-получить выходные данные из нашего скрипта и проверить, соответствует ли он тому, что мы ожидали.

4. Джайтон

Продолжая работу с Jython, у нас также есть возможность встраивать код Python непосредственно в наш Java-код. Мы можем сделать это с помощью класса Pythoninterpreter :

@Test public void givenPythonInterpreter_whenPrintExecuted_thenOutputDisplayed() < try (PythonInterpreter pyInterp = new PythonInterpreter()) < StringWriter output = new StringWriter(); pyInterp.setOut(output); pyInterp.exec("print('Hello Baeldung Readers!!')"); assertEquals("Should contain script output: ", "Hello Baeldung Readers!!", output.toString() .trim()); >>

Использование класса PythonInterpreter позволяет нам выполнить строку исходного кода Python с помощью метода exec /. Как и прежде, мы используем StringWriter для захвата выходных данных этого выполнения.

Теперь давайте рассмотрим пример, где мы складываем два числа вместе:

@Test public void givenPythonInterpreter_whenNumbersAdded_thenOutputDisplayed() < try (PythonInterpreter pyInterp = new PythonInterpreter()) < pyInterp.exec("x = 10+10"); PyObject x = pyInterp.get("x"); assertEquals("x: ", 20, x.asInt()); >>

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

В нашем последнем примере Jython мы увидим, что происходит, когда возникает ошибка:

try (PythonInterpreter pyInterp = new PythonInterpreter())

Когда мы запускаем этот код, возникает Исключение , и мы увидим ту же ошибку, как если бы мы работали с собственным Python:

Traceback (most recent call last): File "", line 1, in ImportError: No module named syds

Несколько моментов, которые мы должны отметить:

  • Поскольку Интерпретатор Python реализует Автоклавируемый , рекомендуется использовать try-with-resources при работе с этим классом
  • Имя класса PythonInterpreter не означает, что наш код Python интерпретируется. Программы Python в Python запускаются JVM и поэтому компилируются в байт-код Java перед выполнением
  • Хотя Jython является реализацией Python для Java, он может содержать не все те же подпакеты, что и родной Python

5. Apache Commons Exec

Еще одной сторонней библиотекой, которую мы могли бы рассмотреть, является Apache Common Exec , которая пытается преодолеть некоторые недостатки API процесса Java|/.

Артефакт commons-exec доступен в Maven Central :

 org.apache.commons commons-exec 1.3 

Теперь давайте посмотрим, как мы можем использовать эту библиотеку:

@Test public void givenPythonScript_whenPythonProcessExecuted_thenSuccess() throws ExecuteException, IOException

Этот пример не слишком отличается от нашего первого примера с использованием ProcessBuilder . Мы создаем объект командной строки для данной команды. Затем мы настроим обработчик потока, который будет использоваться для захвата выходных данных нашего процесса перед выполнением вашей команды.

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

6. Использование HTTP для взаимодействия

Давайте сделаем шаг назад на мгновение и вместо того, чтобы пытаться напрямую вызывать Python, рассмотрим использование хорошо зарекомендовавшего себя протокола, такого как HTTP, в качестве уровня абстракции между двумя разными языками.

На самом деле Python поставляется с простым встроенным HTTP-сервером, который мы можем использовать для обмена контентом или файлами по HTTP :

Если мы сейчас перейдем к http://localhost:9000 , мы увидим содержимое каталога, в котором мы запустили предыдущую команду.

Некоторые другие популярные фреймворки, которые мы могли бы использовать для создания более надежных веб-сервисов или приложений на основе Python, Колба и Джанго .

Как только у нас есть конечная точка, к которой мы можем получить доступ, мы можем использовать любую из нескольких библиотек Java HTTP для вызова нашей реализации веб-службы/приложения Python.

7. Заключение

В этом уроке мы узнали о некоторых из самых популярных технологий для вызова кода Python из Java.

Как всегда, полный исходный код статьи доступен на GitHub .

Читайте ещё по теме:

Источник

Читайте также:  Java list drop down
Оцените статью