web-dev-qa-db-ja.com

JavaでPythonスクリプトからの出力を呼び出して受信しますか?

JavaからPythonスクリプトを実行し、そのスクリプトの出力を受け取る最も簡単な方法は何ですか? JeppやJythonなどのさまざまなライブラリを探しましたが、ほとんどが古くなっています。ライブラリのもう1つの問題は、ライブラリを使用する場合、ライブラリをソースコードに簡単に含めることができる必要があることです(ただし、ライブラリ自体をソースにする必要はありません)。

このため、最も簡単で効果的な方法は、runtime.execを使用してスクリプトを呼び出してから、何らかの方法で印刷出力をキャプチャすることです。または、非常に苦痛ですが、一時テキストファイルにPythonスクリプトを出力して、Javaでファイルを読み取ることもできます。

注:JavaとPythonの間の実際の通信は、解決しようとしている問題の要件ではありません。ただし、これは、必要なことを簡単に実行するための唯一の方法です。

46
404 Not Found

あなたの質問を正しく理解しているかどうかはわかりませんが、コンソールから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/

56
Sevas

Javaプロジェクトに Jython ライブラリを含めることができます。 ソースコードをダウンロード Jythonプロジェクト自体からダウンロードできます。

Jythonは、基本的にJavaからPythonスクリプトを実行できる JSR-22 のサポートを提供します。

ScriptContextを使用して、実行の出力を送信する場所を構成できます。

たとえば、numbers.pyという名前のファイルに次のPythonスクリプトがあるとします。

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でこれを実行しても問題はありません。

29
Edwin Dalorzo

以前にも同じ問題に遭遇し、ここの回答も読んでいますが、互換性、パフォーマンス、フォーマット出力のバランスを取ることができる満足のいく解決策は見つかりませんでした。JythonはCパッケージを拡張し、CPythonよりも低速です。そこでついに自分でホイールを発明することにしました。5泊かかりました。jpserve( https://github.com/johnhuang-cn/jpserve )にも役立つことを願っています。

JPserveは、Pythonを呼び出して、適切な形式のJSONで結果を交換する簡単な方法を提供しますが、パフォーマンスの低下はほとんどありません。以下はサンプルコードです。

最初に、Python側でjpserveを起動します

>>> 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
8
John Huang

JeppやJythonなどのさまざまなライブラリを探しましたが、ほとんどは非常に古いようです。

Jythonは「ライブラリ」ではありません。 Python仮想マシンの上にあるJava言語の実装です。決して時代遅れではありません。最新のリリースは今年の2月24日でした。これはPython 2.5を実装します。つまり、いくつかの最新の機能が欠けていることを意味しますが、正直なところ、2.7とそれほど違いはありません。

注:JavaとPythonの間の実際の通信は前述の割り当ての要件ではないため、これは私の宿題をしていません。ただし、これは、必要なことを簡単に実行するための唯一の方法です。

これは、極端に学校の課題ではありそうにないようです。あなたが何をしているかについてもっと教えてください本当にやろうとしていること。通常、学校の課題では、何にどの言語を使用するかを正確に指定しますが、複数の言語が関係する言語を聞いたことはありません。もしそうなら、彼らはあなたがこの種のコミュニケーションをセットアップする必要があるかどうか、そして彼らがあなたにそれをするつもりだった方法を教えてくれるでしょう。

5
Karl Knechtel

Jep は別のオプションです。 JNIを介してJavaにCPythonを埋め込みます。

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");
    }
2
Ariel

Jythonアプローチ

Javaはプラットフォームに依存しないと想定されており、ネイティブアプリケーション(Pythonなど)を呼び出すことは、プラットフォームにあまり依存していません。

Javaで記述されたPython(Jython)のバージョンがあり、PythonプログラムにJavaを埋め込むことができます。通常、外部ライブラリを使用するときのハードルは、コンパイルして正しく実行することです。そのため、Jythonを使用して簡単なJavaプログラムをビルドおよび実行するプロセスを実行します。

まず、jython jarファイルを取得します。

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

Jython-2.5.3.jarを、Javaプログラムが置かれるディレクトリにコピーしました。次に、次のプログラムを入力しました。これは、前の2つと同じです。 2つの番号を取得し、それらを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

これにより、プラットフォームに依存しない方法で、JavaのPythonを使用できるようになりました。ちょっと遅いです。それでも、それは、Javaで書かれたPythonインタープリターであるというのはちょっとクールです...

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
1
txominpelu

まず、ProcessBuilderを使用することをお勧めします(1.5以降)
簡単な使用法については、こちらをご覧ください
https://stackoverflow.com/a/14483787
より複雑な例については、を参照してください
http://www.javaworld.com/article/2071275/core-Java/when-runtime-exec---won-t.html

JavaからPythonスクリプトを起動するときに問題が発生しました。スクリプトは標準出力に大量の出力を生成し、すべてがうまくいきませんでした。

1
partTimeNinja

達成するための最良の方法は、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の完全なソースコードがここで共有されており、この別の懸念に対処しています post ;

https://github.com/raohammad/externalprocessfromjava.git

0
khawarizmi