web-dev-qa-db-ja.com

JavaでPythonを呼び出しますか?

Jythonを使用してpythonコードからJava関数を呼び出すことができるのか、それともpythonからJavaコードを呼び出すためだけなのか疑問に思っています。

100
Shahab

Jython:Python for Java Platform- http://www.jython.org/index.html

Jythonを使用すると、pythonコードからJava関数を簡単に呼び出すことができます。 pythonコード自体がjythonの下で実行されている限り、つまり、サポートされていない一部のc拡張を使用していません。

それがあなたのために働く場合、それは確かにあなたが得ることができる最も簡単な解決策です。それ以外の場合は、新しいJava6インタープリターサポートのorg.python.util.PythonInterpreterを使用できます。

私の頭の上からの簡単な例-しかし、うまくいくはずです:(簡潔にするためにエラーチェックは行われません)

PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec("import sys\nsys.path.append('pathToModules if they are not there by default')\nimport yourModule");
// execute a function that takes a string and returns a string
PyObject someFunc = interpreter.get("funcName");
PyObject result = someFunc.__call__(new PyString("Test!"));
String realResult = (String) result.__tojava__(String.class);
89
Voo

ちょっと遅かったのに、これに対する私の答えを入力すると思いました。 Javaとpythonの間のリンクをどのくらい強くしたいかについて、最初に考慮すべき重要な点があると思います。

まず関数を呼び出すだけですか、それともpythonコードでJavaオブジェクトのデータを変更するだけですか?これはとても重要です。引数を使用して、または使用せずにpythonコードのみを呼び出す場合は、それほど難しくありません。引数がプリミティブである場合、さらに簡単になります。ただし、JavaクラスにPythonのメンバー関数を実装させ、Javaオブジェクトのデータを変更したい場合、これはそれほど簡単でも簡単でもありません。

第二に私たちはcpythonを話しているのですか、それともjythonはしますか?私はcpythonがどこにあると言うでしょう!これが、pythonがとてもクールな理由です。ただし、必要に応じてc、c ++にアクセスするような高い抽象化を備えています。 Javaでそれを実現できると想像してください。この質問は、jythonが大丈夫かどうかを尋ねる価値さえありません。

そこで、次の方法を試し、簡単なものから難しいものまでリストしました。

JavaからJython

利点:簡単です。 Javaオブジェクトへの実際の参照がある

欠点:CPythonがなく、非常に遅い!

JavaのJythonはとても簡単です。これで本当に十分であれば、素晴らしいことです。しかし、それは非常に遅く、cpythonはありません! cpythonなしで生活する価値はあると思います。 pythonオブジェクトのメンバー関数を実装するJavaコードを簡単に作成できます。

パイロ経由でJavaからJython、CPythonへ

Pyroは、Pythonのリモートオブジェクトモジュールです。 cpythonインタープリターにオブジェクトがあり、シリアル化を介して転送されるオブジェクトを送信できます。また、このメソッドを介してオブジェクトを返すこともできます。シリアル化されたpythonオブジェクトをjythonから送信し、そのメンバーのデータを変更するいくつかの関数を呼び出すと、Javaでそれらの変更が表示されないことに注意してください。パイロから必要なデータを送り返すことを忘れないでください。これがcpythonに到達する最も簡単な方法だと思います! jni、jna、swig、...は必要ありません。cやc ++を知っている必要はありません。かっこいい?

利点:cpythonへのアクセス、次の方法ほど難しくない

欠点:JavaオブジェクトのメンバーデータをPythonから直接変更することはできません。やや間接的です(jythonは仲介者です)。

JavaからJNI/JNA/SWIG経由でC/C++へ、埋め込みインタープリター経由でPythonへ(おそらくBOOSTライブラリを使用しますか?)

OMGこの方法は、弱い人向けではありません。そして、まともな方法でこれを達成するのに非常に長い時間がかかったと言うことができます。これを行う主な理由は、Javaオブジェクトを完全に制御するcpythonコードを実行できるようにするためです。 Java(チンパンジーのようなもの)とpython(馬のようなもの)を試してみることにする前に、考慮すべき主要な主要事項があります。第一に、あなたのプログラムにとって消灯しているインタプリタをクラッシュさせた場合です!そして、並行性の問題を始めさせないでください!さらに、ボイラーの割り当てがあります。このボイラーを最小化するのに最適な構成を見つけたと思いますが、それでも割り当てられています。だからこれをどうやってやるのか:C++があなたの仲介者であり、あなたのオブジェクトは実際にはc ++オブジェクトだと考えてください!あなたが今知っていることは良いことです。両方の世界からアクセスしたいデータを使用して、Javaではなくcppのようにプログラムを作成します。次に、swigというラッパージェネレーター( http://www.swig.org/Doc1.3/Java.html )を使用して、これをJavaにアクセス可能にし、dllをコンパイルします。 JavaでSystem.load(ここではdll名)を呼び出します。最初にこれを機能させてから、難しい部分に進んでください! pythonに到達するには、インタープリターを埋め込む必要があります。まず、Helloインタープリタープログラムまたはこのチュートリアルを行うことをお勧めします C/Cのpythonを埋め込む 。それができたら、馬と猿を踊らせる時間です! [boost] [3]を介してpythonにc ++オブジェクトを送信できます。私はあなたに魚を与えていないことを知っています、ただ魚を見つける場所をあなたに話しました。コンパイル時に注意すべきいくつかのポインタ。

Boostをコンパイルするときは、共有ライブラリをコンパイルする必要があります。そして、jdkから必要なもの、つまりjawt.lib、jvm.libをインクルードしてリンクする必要があります(アプリケーションを起動するときにパスにクライアントjvm.dllも必要になります)python27.libまたは何でも、boost_python-vc100-mt-1_55.lib。次に、Python/include、jdk/include、boostをインクルードし、共有ライブラリー(dll)のみを使用します。そうしないと、boostが破損します。そしてええ、私は知っています。これが酸っぱくなり得る多くの方法があります。したがって、ブロックごとに各処理を実行してください。次に、それらをまとめます。

56
Snickers3192

Java内でpythonコードを使用するのは賢くありません。 pythonコードをflaskまたはその他のWebフレームワークでラップして、マイクロサービスとして作成します。 Javaプログラムがこのマイクロサービスを呼び出すことができるようにします(REST経由など)。

私を信じて、これは非常に簡単であり、あなたの問題のトンを保存します。また、コードは疎結合であるため、スケーラブルです。

12
Peiming Hu

いくつかの回答では、JNIまたはJNAを使用してcpythonにアクセスできると述べていますが、Javaからcpythonにアクセスするためのオープンソースライブラリが既にあるため、ゼロから始めることはお勧めしません。例えば:

9
bsteffen

ここでは、pythonスクリプトを1回記述し、実行時に使用する統合方法(Jython、JepおよびPy4jを介したCPython/PyPy)を決定できるライブラリがあります。

https://github.com/subes/invesdwin-context-python

各メソッドには、リンクで説明されているように、独自の利点/欠点があるためです。

7
subes

python関数の意味に依存しますか?それらが cpython で記述されている場合、直接呼び出すことはできません JNI を使用する必要がありますが、 Jython で記述されている場合jythonは最終的にJavaバイトコードを生成するため、Javaから簡単に呼び出すことができます。

Cpythonまたはjythonで書かれていると言うと、pythonはpythonであり、cpythonに依存する特定のライブラリを使用していない限り、ほとんどのコードは両方の実装で実行されるため、あまり意味がありませんまたはJava。

こちらをご覧ください JavaでのPythonインタープリターの使用方法

4
Anurag Uniyal

要件に応じて、 XML-RPC などのオプションが便利な場合があります。これは、プロトコルをサポートする任意の言語で関数をリモートで呼び出すために使用できます。

4
Timo

Java Native Interface を使用して、Javaから任意の言語を呼び出すことができます。

3
nidhin

Jythonにはいくつかの制限があります。

いくつかの違いがあります。まず、JythonプログラムはCで記述されたCPython拡張モジュールを使用できません。これらのモジュールには通常、拡張子が.so、.pyd、または.dllのファイルがあります。このようなモジュールを使用する場合は、純粋なPythonまたはJavaで記述された同等のものを探す必要があります。そのような拡張機能をサポートすることは技術的に実行可能ですが、IronPythonはサポートしますが、Jythonでサポートする予定はありません。

JythonでPythonスクリプトをJARファイルとして配布しますか?

runtimeまたはProcessBuilderを使用してpythonからJavaスクリプト(またはbashまたはPerlスクリプト)を呼び出して、出力をJavaに戻すことができます。

Javaでbashシェルスクリプトを実行

Javaでコマンドラインを実行

Java runtime.getruntime()コマンドラインプログラムの実行による出力の取得

2
alex