在Java中调用Python?
我想知道是否有可能从java代码使用jython调用python函数,还是只是从python调用java代码?
您可以使用Jython从Java代码轻松调用python函数。 只要你的python代码本身在jython下运行,即不使用一些不被支持的c-extensions。
如果这对你有用,这当然是你可以得到的最简单的解决scheme。 否则,您可以使用新的Java6解释器支持中的org.python.util.PythonInterpreter
。
一个简单的例子,从我的头顶 – 但应该工作,我希望:(没有错误检查简洁)
PythonInterpreter interpreter = new PythonInterpreter(); interpreter.exec("import sys\nsys.path.append('pathToModiles if they're 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);
嘿,我以为我会input我的答案,即使它迟了。 我认为有一些重要的事情要考虑,首先要考虑你想在java和python之间build立链接的强度。
首先 ,你只是想调用函数,或者你真的想要python代码来改变你的java对象的数据? 这个非常重要。 如果你只想调用一些有或没有参数的python代码,那么这不是很困难。 如果你的论点是原始的,那么它就更容易了。 但是如果你想在java中实现java类的实现成员函数,这会改变java对象的数据,那么这不是那么容易或者直接。
其次是我们说cpython还是会用jython呢? 我会说cpython是在哪里! 我会主张这是为什么python是如此kool! 有这样高的抽象,但是需要时访问C,C ++。 想象一下,如果你可以在java中有这样的。 这个问题甚至不值得问jython是否可以,因为反正很简单。
所以我玩了下面的方法,把它们从易到难列举出来:
Java到Jython
优点:非常简单。 有实际的Java对象引用
缺点:没有CPython,非常慢!
来自java的Jython非常简单,如果这真的够了,那就太棒了。 但是它很慢,没有cpython! 没有cpython的生活是值得的生活我不这么认为! 你可以很容易地为你的java对象实现你的成员函数的python代码。
Java到Jython通过Pyro到CPython
Pyro是python的远程对象模块。 你在cpython解释器上有一些对象,你可以发送它通过序列化传送的对象,也可以通过这个方法返回对象。 请注意,如果您从jython发送一个序列化的python对象,然后调用一些更改其成员中的数据的函数,那么您将不会在java中看到这些更改。 你只需要记住从pyro发回你想要的数据。 这我相信是最简单的方法来cpython! 您不需要任何jni或jna或swig或….您不需要知道任何c或c ++。 酷吧?
优点:访问cpython,不像以下方法那么困难
缺点:不能直接从python中更改java对象的成员数据。 有点间接,(jython是中间人)。
Java到C / C ++通过JNI / JNA / SWIG到Python通过embedded式解释器(也许使用BOOST库?)
OMG这个方法并不是为了心灰意懒。 而且我可以告诉你,用一种体面的方法来达到这个目标已经花了我很长时间了。 你想这样做的主要原因是,你可以运行cpython代码,这完全掌握你的java对象。 在决定尝试使用python(就像一匹马)和面包java(就像一个黑猩猩)之前,有一些主要的事情要考虑。 首先,如果你的解释器崩溃了,你的程序灯灭了! 不要让我开始并发问题! 另外,还有锅炉的配量,我相信我已经find最好的configuration来尽量减less这个锅炉,但它仍然是分配! 所以如何去做这件事:考虑到C ++是你的中间人,你的对象实际上是c ++对象! 好的,你现在知道了。 只需将你的对象写成如同你的程序一样在cpp而不是java中,用你想从两个世界访问的数据。 然后你可以使用名为swig的包装生成器( http://www.swig.org/Doc1.3/Java.html )使这个访问到Java和编译一个DLL,你可以调用System.load(在这里的DLL名称) java的。 首先得到这个工作,然后继续努力! 要得到Python,你需要embedded一个解释器。 首先,我build议做一些hello解释程序或本教程在C / C中embeddedpython 。 一旦你有这个工作,它的时间,使马和猴子跳舞! 您可以通过[boost] [3]将c ++对象发送给python。 我知道我没有给你鱼,只是告诉你在哪里找鱼。 编译时需要注意的一些指针。
当你编译boost时,你将需要编译一个共享库。 你需要包括和链接到你需要从jdk的东西,即jawt.lib,jvm.lib,(当启动应用程序时,您还需要在您的path客户端jvm.dll)以及python27.lib或不pipe什么和boost_python-vc100-mt-1_55.lib。 然后包括Python / include,jdk / include,boost,只使用共享库(dll),否则boost有一个泪痕。 而且我知道, 有这么多的方式可以发酸。 所以一定要把每一件事情都做好。 然后把它们放在一起。
这取决于你是什么意思的Pythonfunction? 如果它们是用cpython编写的,你不能直接调用它们,你将不得不使用JNI ,但是如果它们是用Jython编写的,你可以很容易地从java调用它们,因为jython最终生成java字节码。
现在,当我用cpython或jython编写时,没有什么意义,因为python是python,大多数代码都可以在两种实现上运行,除非您使用依赖于cpython或java的特定库。
在这里看到如何在Java中使用Python解释器。
您可以使用Java Native Interface从Java中调用任何语言
根据您的要求,像XML-RPC这样的选项可能是有用的,它可以用来以任何支持协议的语言虚拟地远程调用function。
几个答案提到,你可以使用JNI或JNA来访问cpython,但是我不build议从头开始,因为已经有用于从java访问cpython的开源库。 例如:
- JEP
- 日元
Jython有一些限制:
有一些差异。 首先,Jython程序不能使用用C编写的CPython扩展模块。这些模块通常具有扩展名为.so,.pyd或.dll的文件。 如果你想使用这样的模块,你应该寻找一个用纯Python或Java编写的等价物。 尽pipe支持这种扩展在技术上是可行的,但IronPython是这样做的 – 在Jython中没有这样做的计划。
用Jython将我的Python脚本分发为JAR文件?
您可以使用Runtime或ProcessBuilder从Java调用python脚本(或bash或Perl脚本),并将输出传回给Java:
在java中运行一个bash shell脚本
在Java中运行命令行
java runtime.getruntime()从执行命令行程序获取输出
这里有一个库,可以让你编写一次python脚本,并决定在运行时使用哪种集成方法(通过Jep和Py4j实现Jython,CPython / PyPy)
https://github.com/subes/invesdwin-context-python
由于每种方法都有自己的好处/缺点,如链接所述。
在java中有python代码是不聪明的。 用烧瓶或其他Web框架包装你的python代码,使其成为一个微服务。 让你的Java程序能够调用这个微服务(例如通过REST)。
相信我,这很简单,将为您节省大量的问题。 代码是松耦合的,所以它们是可扩展的。