Вопрос по java, python – Вызывать и получать вывод из скрипта Python на Java?

41

Какой самый простой способ выполнить сценарий Python из Java и получить выходные данные этого сценария? Я искал разные библиотеки, такие как Jepp или Jython, но большинство из них устарели. Другая проблема с библиотеками заключается в том, что мне нужно иметь возможность легко включать библиотеку с исходным кодом (хотя мне не нужен источник для самой библиотеки), если я использую библиотеку.

Из-за этого будет ли самый простой / эффективный способ просто сделать что-то вроде вызова скрипта с помощью runtime.exec, а затем каким-то образом перехватить вывод на печать? Или, даже если мне будет очень больно, я мог бы просто вывести вывод сценария Python во временный текстовый файл, а затем прочитать файл на Java.

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

Я проверил предыдущий ответ Джона Хуанга, опубликованный здесьgit hub project jpserve Это лучшее решение, потому что оно связывает java-клиент с реальным приложением Python, которое может выполнять ваши скрипты, файлы, ... Это хорошо для очень сложных проектов, где вам нужно последнее обновление библиотеки Python, например Tensorflow, ... Единственная проблема Это то, что вы должны делать все за один сеанс (не как в переводчике), поэтому вы должны работать над подготовкой своего отзыва обратно в Java. Но это очень просто по сравнению с установкой Tensorflow в библиотеках Java Python Спасибо [Джо Dorin

Ваш Ответ

8   ответов
2

Jep это другой вариант. ВстраиваетCPython в Java через JNI.

//...
    try(Jep jep = new Jep(false)) {
        jep.eval("s = 'hello world'");
        jep.eval("print(s)");
        jep.eval("a = 1 + 2");
        Long a = (Long) jep.getValue("a");
    }
1

)
 Простое использование описано здесь
https://stackoverflow.com/a/14483787
Для более сложного примера обратитесь к
http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html

Я столкнулся с проблемой при запуске скрипта Python из Java, скрипт производил слишком много продукции, чтобы вывести ее из стандартного уровня, и все пошло плохо

52

что я правильно понял ваш вопрос, но при условии, что вы можете вызвать исполняемый файл Python из консоли и просто захотеть записать его вывод в Java, вы можете использоватьexec() метод в JavaRuntime учебный класс.

Process p = Runtime.getRuntime().exec("python yourapp.py");

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

http://www.devdaily.com/java/edu/pj/pj010016

Существует также библиотека Apache (проект Apache exec), которая может помочь вам в этом. Вы можете прочитать больше об этом здесь:

http://www.devdaily.com/java/java-exec-processbuilder-process-1

http://commons.apache.org/exec/

Я думал о создании механизма рабочего процесса, в котором функции рабочего процесса будут представлять собой скрипты Python, а механизм - само приложение на основе Java. Знаете ли вы, каковы будут затраты на производительность при непрерывном вызове небольших сценариев Python один за другим?
@Janac Meena Я попробовал метод абсолютного пути, который вы указали, и он не выдает ошибку. Однако моя программа на python не генерирует вывод из java (eclipse ide). Моя программа на python просто создает текстовый файл в рабочий стол.
@joeybaruch Я решил эту проблему, указав абсолютный путь к моему исполняемому файлу python, т.е.Runtime.getRuntime().exec("C:\\Python27\\python.exe yourapp.py")
@ user123, если ошибки нет, возможно, проблема в вашем скрипте Python. Вы успешно запустили свой скрипт за пределами Java-приложения?
БегRuntime.getRuntime().exec("python yourapp.py"); бросил исключение:java.io.IOException: Cannot run program "python": CreateProcess error=2, The system cannot find the file specified пожалуйста, обратите внимание, что python является частью моей переменной PATH
1

ет отличной поддержкой для запуска внешних процессов и извлечения выходных данных:

http://groovy.codehaus.org/Executing+External+Processes+From+Groovy

Вы можете видеть в этом коде, взятом из той же ссылки, как groovy позволяет легко получить статус процесса:

println "return code: ${ proc.exitValue()}"
println "stderr: ${proc.err.text}"
println "stdout: ${proc.in.text}" // *out* from the external program is *in* for groovy
7

также прочитал ответы здесь, но не нашел, что какое-либо удовлетворительное решение может сбалансировать совместимость, производительность и форматирование выходных данных, Jython не может работать с пакетами расширения C и медленнее, чем CPython. Поэтому, наконец, я решил изобрести колесо сам, это заняло у меня 5 ночей, я надеюсь, что это может помочь вам тоже: jpserve (https://github.com/johnhuang-cn/jpserve).

JPserve предоставляет простой способ вызова Python и обмена результатами путем форматирования JSON, что приводит к небольшому снижению производительности. Ниже приведен пример кода.

Сначала запустите jpserve на стороне Python

>>> from jpserve.jpserve import JPServe
>>> serve = JPServe(("localhost", 8888))
>>> serve.start()

INFO:JPServe:JPServe starting...
INFO:JPServe:JPServe listening in localhost 8888

Затем вызовите Python со стороны JAVA:

PyServeContext.init("localhost", 8888);
PyExecutor executor = PyServeContext.getExecutor();
script = "a = 2\n"
    + "b = 3\n"
    + "_result_ = a * b";

PyResult rs = executor.exec(script);
System.out.println("Result: " + rs.getResult());

---
Result: 6
Вы можете прочитатьHow to offer personal open-source libraries? перед публикацией о вашем проекте.
Я заметил, что после выполнения скрипта он не запоминает свои переменные, то есть, например, загрузка файла объемом 500 ГБ должна выполняться при каждом вызове. Можно ли инициализировать некоторые переменные или сохранить их в памяти?
Вы можете установить глобальную переменную в скрипте. Насколько я помню, Python может устанавливать глобальную переменную явно. Я уже забыл подробный синтаксис, так как давно не писал сценарий Python.
Спасибо за ваше предложение.
2

Jython approach

Предполагается, что Java не зависит от платформы, и вызов нативного приложения (например, Python) не очень зависит от платформы.

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

Начнем с получения jar-файла jython:

http://www.jython.org/downloads.html

Я скопировал jython-2.5.3.jar в каталог, где должна была быть моя Java-программа. Затем я набрал следующую программу, которая делает то же самое, что и две предыдущие; возьмите два числа, отправьте их в python, который добавляет их, затем python вернет их обратно в нашу программу Java, где число выводится на экран:

import org.python.util.PythonInterpreter; 
import org.python.core.*; 

class test3{
    public static void main(String a[]){

        PythonInterpreter python = new PythonInterpreter();

        int number1 = 10;
        int number2 = 32;
        python.set("number1", new PyInteger(number1));
        python.set("number2", new PyInteger(number2));
        python.exec("number3 = number1+number2");
        PyObject number3 = python.get("number3");
        System.out.println("val : "+number3.toString());
    }
}

Я называю этот файл «test3.java», сохраняю его и делаю следующее для его компиляции:

javac -classpath jython-2.5.3.jar test3.java

Следующий шаг - попытаться запустить его, что я делаю следующим образом:

java -classpath jython-2.5.3.jar :. test3

Теперь это позволяет нам использовать Python из Java независимо от платформы. Это довольно медленно. Тем не менее, это круто, что это интерпретатор Python, написанный на Java ...

28

Jython библиотека в вашем проекте Java. Вы можетескачать исходный код из самого проекта Jython.

Jython предлагает поддержкуJSR-223 который в основном позволяет вам запускать скрипт Python из Java.

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

Например, предположим, у вас есть следующий скрипт Python в файле с именемnumbers.py:

for i in range(1,10):
    print(i)

Итак, вы можете запустить его из Java следующим образом:

public static void main(String[] args) throws ScriptException, IOException {

    StringWriter writer = new StringWriter(); //ouput will be stored here

    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptContext context = new SimpleScriptContext();

    context.setWriter(writer); //configures output redirection
    ScriptEngine engine = manager.getEngineByName("python");
    engine.eval(new FileReader("numbers.py"), context);
    System.out.println(writer.toString()); 
}

И вывод будет:

1
2
3
4
5
6
7
8
9

Пока ваш скрипт Python совместим с Python 2.5, у вас не возникнет никаких проблем при запуске этого с Jython.

извините, но вы использовали здесь какой-нибудь jython? все, что вы использовали, это функции библиотеки Java Std?
Jython является реализацией Python для JVM,it won't work with C extensions такой как NumPy.
Я не понимаю. Numbers.py - полный путь к скрипту Python? Это не работает для меня.
ScriptEngine нуждается в jython для пути к классам, иначе «движок»; нулевой
4

ve looked for different libraries like Jepp or Jython, but most seem to be very out of date.

Jython не является "библиотекой"; это реализация языка Python поверх виртуальной машины Java. Это определенно не устарело; последний релиз был 24 февраля этого года. Он реализует Python 2.5, что означает, что вам не хватает нескольких более свежих функций, но, честно говоря, он не сильно отличается от 2.7.

Note: the actual communication between Java and Python is not a requirement of the aforementioned assignment, so this isn't doing my homework for me. This is, however, the only way I can think of to easily perform what needs to be done.

Это кажетсяextremely вряд ли для школьного задания. Пожалуйста, расскажите нам больше о том, что выreally пытаюсь сделать. Обычно школьные задания точно определяют, какие языки вы для чего будете использовать, и я никогда не слышал о языке, который бы вообще включал более одного языка. Если это произойдет, они скажут вам, нужно ли вам устанавливать такой тип связи, и как они намеревались это сделать.

Черт, ну, похоже, даже Python не поддерживает выражения, которые я пытаюсь использовать. Полагаю, мне все равно придется переделывать. 404 Not Found
Балансировка скобок выходит за рамки того, что обычно можно назвать регулярным выражением, и выходит за рамки того, что строго называется регулярным выражением. На самом деле, это в значительной степени канонический пример того, что выcan't делать с регулярными выражениями.
«Больше логического кодирования для разбора строки» будетmuch меньше усилий, независимо от того, какие два языка вы хотите использовать вместе или как вы планируете это делать. Доверьтесь мне. Почему вы не задаете вопрос, который вас действительно интересует, т.е.how to parse the string? Опять же, поскольку это школьное задание, оно почти наверняка не означает, что вы используете расширенные функции регулярных выражений.
Вы правы в обоих случаях. Я действительно знал, что Jython все еще обновляется, я просто не уточнил. Во-вторых, я действительно пытаюсь разобрать строку с помощью регулярных выражений, однако, выражение, которое я использую, не поддерживается в Java. Да, есть способы, которыми я мог бы сделать это, используя только Java с более простыми выражениями, но это означало бы больше логического кодирования для анализа строки, в то время как этот метод (то есть текущее регулярное выражение, которое я использую) дает мне в значительной степени именно то, что Я нуждаюсь. 404 Not Found
Хорошо, регулярное выражение, которое я пытался использовать, состояло в том, чтобы получить соответствующие круглые скобки, используя балансирующие группы, но, очевидно, это поддерживается только языками .NET. В конце я просто прекратил попытки делать вложенные (так как это не требовалось) и просто изменил их на один уровень. 404 Not Found

Похожие вопросы