63

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

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

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

4

10 に答える 10

75

あなたの質問を正しく理解しているかどうかはわかりませんが、コンソールからPython実行可能ファイルを呼び出して、その出力をJavaでキャプチャしたい場合は、Javaクラスのexec()メソッドを使用できます。Runtime

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

このリソースからの出力を実際に読み取る方法については、次の URLを参照してください。http ://www.devdaily.com/java/edu/pj/pj010016 import java.io. *;

public class JavaRunCommand {

    public static void main(String args[]) {

        String s = null;

        try {
            
        // run the Unix "ps -ef" command
            // using the Runtime exec method:
            Process p = Runtime.getRuntime().exec("ps -ef");
            
            BufferedReader stdInput = new BufferedReader(new 
                 InputStreamReader(p.getInputStream()));

            BufferedReader stdError = new BufferedReader(new 
                 InputStreamReader(p.getErrorStream()));

            // read the output from the command
            System.out.println("Here is the standard output of the command:\n");
            while ((s = stdInput.readLine()) != null) {
                System.out.println(s);
            }
            
            // read any errors from the attempted command
            System.out.println("Here is the standard error of the command (if any):\n");
            while ((s = stdError.readLine()) != null) {
                System.out.println(s);
            }
            
            System.exit(0);
        }
        catch (IOException e) {
            System.out.println("exception happened - here's what I know: ");
            e.printStackTrace();
            System.exit(-1);
        }
    }
}

これを支援するApacheライブラリ(Apache execプロジェクト)もあります。あなたはここでそれについてもっと読むことができます:

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

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

于 2012-04-10T22:48:11.283 に答える
34

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

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

を使用し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スクリプトがPython2.5と互換性がある限り、Jythonでこれを実行しても問題はありません。

于 2012-04-10T23:29:01.933 に答える
8

私は以前に同じ問題に遭遇し、ここでも回答を読みましたが、互換性、パフォーマンス、および適切な形式の出力のバランスをとることができる満足のいくソリューションは見つかりませんでした。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

次に、JAVA側からPythonを呼び出します。

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
于 2016-10-11T09:05:48.737 に答える
4

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

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

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

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

于 2012-04-10T23:15:16.173 に答える
3

Jythonアプローチ

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

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

まず、jythonjarファイルを入手します。

https://www.jython.org/download.html

jython-2.5.3.jarをJavaプログラムが配置されるディレクトリにコピーしました。次に、前の2つと同じように実行する次のプログラムを入力しました。2つの数値を取得し、それらをpythonに送信します。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インタープリターであることはちょっとクールです。

于 2017-04-09T11:34:57.160 に答える
3

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");
    }
于 2017-07-04T10:36:10.170 に答える
2

ProcessBuilderは非常に使いやすいです。

ProcessBuilder pb = new ProcessBuilder("python","Your python file",""+Command line arguments if any);
Process p = pb.start();

これはpythonを呼び出す必要があります。完全な例については、ここでのプロセスアプローチを参照してください。

https://bytes.com/topic/python/insights/949995-three-ways-run-python-programs-java

于 2019-09-10T06:31:46.247 に答える
1

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
于 2012-04-10T23:02:01.217 に答える
1

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

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

于 2013-12-18T14:54:02.880 に答える
0

達成するための最良の方法は、Apache Commons Execを使用することです。これは、ウォッチドッグを使用して外部プロセス(python、bashなどを含む)synchronousを実行できるため、Java8環境でも問題なく本番環境で使用できます。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

于 2019-05-16T11:09:56.017 に答える