Подтвердить что ты не робот

Вызывать и получать вывод из Python script в Java?

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

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

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

4b9b3361

Ответ 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. См. процессный подход здесь для полного примера!