Вызывать и получать вывод из Python script в Java?
Какой самый простой способ выполнить Python script с Java и получить вывод этого script? Я искал разные библиотеки, такие как Jepp или Jython, но большинство из них устарели. Еще одна проблема с библиотеками заключается в том, что мне нужно иметь возможность легко включать библиотеку с исходным кодом (хотя мне не нужно использовать исходную для самой библиотеки), если я использую библиотеку.
Из-за этого самым простым и эффективным способом было бы просто сделать что-то вроде вызова script с runtime.exec, а затем каким-то образом захватить печатный результат? Или, хотя это было бы очень болезненно для меня, я мог бы просто получить вывод Python script во временный текстовый файл, а затем прочитать файл на Java.
Примечание: фактическая связь между Java и Python не является требованием к проблеме, которую я пытаюсь решить. Это, однако, единственный способ, с помощью которого я могу легко выполнить то, что нужно сделать.
Ответы
Ответ 1
Не уверен, правильно ли я понял ваш вопрос, но при условии, что вы можете вызывать исполняемый файл Python с консоли и просто хотите записать его вывод в Java, вы можете использовать метод exec()
в классе Java Runtime
.
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/
Ответ 2
Вы можете включить библиотеку Jython в свой Java-проект. Вы можете загрузить исходный код из самого проекта Jython.
Jython предлагает поддержку JSR-223, которая в основном позволяет запускать Python script с Java.
Вы можете использовать ScriptContext
, чтобы настроить, куда вы хотите отправить результат выполнения.
Например, предположим, что у вас есть следующий Python script в файле с именем 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 script совместим с Python 2.5, у вас не будет проблем с запуском этого с Jython.
Ответ 3
Я встречал ту же проблему раньше, также прочитал ответы здесь, но не нашел ни одного удовлетворительного решения, которое могло бы сбалансировать совместимость, производительность и форматирование вывода, 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
Ответ 4
Я искал разные библиотеки, такие как Jepp или Jython, но большинство из них, похоже, очень устарело.
Jython не является "библиотекой"; это реализация языка Python поверх виртуальной машины Java. Это определенно не устарело; последний выпуск был 24 февраля этого года. Он реализует Python 2.5, что означает, что вам не хватало пару новых функций, но это, честно говоря, не сильно отличается от 2.7.
Примечание: фактическая связь между Java и Python не является требованием вышеупомянутого задания, так что это не делает мою домашнюю работу для меня. Это, однако, единственный способ, с помощью которого я могу легко выполнить то, что нужно сделать.
Это кажется крайне маловероятным для школьного задания. Расскажите, пожалуйста, о том, что вы действительно пытаетесь сделать. Обычно школьные задания точно определяют, какие языки вы будете использовать для чего, и я никогда не слышал об одном, в котором участвовало более одного языка вообще. Если бы это произошло, они сказали бы вам, нужно ли вам настраивать такое общение и как они намеревались это сделать.
Ответ 5
Подход Jython
Предполагается, что 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...
Ответ 6
Jep является опцией. Он внедряет CPython в Java через JNI.
import jep.Jep;
//...
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");
}
Ответ 7
Вы можете попробовать использовать groovy. Он работает на JVM, и он отлично поддерживает запуск внешних процессов и извлечение вывода:
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
Ответ 8
Сначала я бы рекомендовал использовать ProcessBuilder (начиная с 1.5)
Простое использование описано здесь
fooobar.com/questions/193120/...
Для более сложного примера см.
http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html
Я столкнулся с проблемой при запуске Python script из Java, script
производил слишком много средств для стандартизации, и все шло плохо.
Ответ 9
Лучший способ добиться этого - использовать Apache Commons Exec, поскольку я использую его для производства без проблем, даже для среды Java 8, поскольку он позволяет выполнять любые внешние процессы (включая python, bash и т.д.) В synchronous
и asynchronous
путь с помощью сторожевых псов.
CommandLine cmdLine = new CommandLine("python");
cmdLine.addArgument("/my/python/script/script.py");
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
ExecuteWatchdog watchdog = new ExecuteWatchdog(60*1000);
Executor executor = new DefaultExecutor();
executor.setExitValue(1);
executor.setWatchdog(watchdog);
executor.execute(cmdLine, resultHandler);
// some time later the result handler callback was invoked so we
// can safely request the exit value
resultHandler.waitFor();
Здесь представлен общий исходный код небольшого, но полного POC, который решает другую проблему в этом посте;
https://github.com/raohammad/externalprocessfromjava.git
Ответ 10
ProcessBuilder очень прост в использовании.
ProcessBuilder pb = new ProcessBuilder("python","Your python file",""+Command line arguements if any);
Process p = pb.start();
Это должно вызвать Python. См. процессный подход здесь для полного примера!