在Java中调用Python?

2022-08-31 08:35:39

我想知道是否可以使用Jython从Java代码调用Python函数,或者它仅用于从Python调用Java代码?


答案 1

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

您可以使用Jython轻松地从Java代码中调用python函数。只要你的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);

截至2021年,Jython不支持Python 3.x。


答案 2

我认为首先需要考虑一些重要的事情,即您希望在java和python之间建立链接的强度。

首先您是只想调用函数,还是真的希望python代码更改Java对象中的数据?这一点非常重要。如果你只想调用一些有或没有参数的python代码,那么这不是很困难。如果你的论点是原语,它使它变得更加容易。但是,如果你想让java类在python中实现成员函数,这些函数会改变java对象的数据,那么这并不容易或直接。

其次,我们是在谈论cpython还是jython会这样做?我会说cpython是它所在的地方!我会提倡这就是为什么python如此kool!具有如此高的抽象,但是在需要时可以访问c,c ++。想象一下,如果你能在java中拥有它。这个问题甚至不值得问jython是否还好,因为无论如何它都很容易。

所以我玩了以下方法,并将它们从简单到困难列出:

Java to Jython

优势:非常简单。对 Java 对象有实际引用

弊:没有CPython,非常慢!

来自java的Jython非常容易,如果这真的足够了,那就太好了。然而,它非常慢,没有cpython!没有cpython的生活值得生活吗我不这么认为!您可以轻松地让python代码为java对象实现成员函数。

Java to Jython to CPython via Pyro

Pyro是python的远程对象模块。你在cpython解释器上有一些对象,你可以向它发送通过序列化传输的对象,它也可以通过这种方法返回对象。请注意,如果您从 jython 发送一个序列化的 python 对象,然后调用一些更改其成员中数据的函数,那么您将无法在 java 中看到这些更改。您只需要记住从pyro中发回您想要的数据即可。我相信这是获得cpython的最简单方法!你不需要任何jni或jna或swig或....你不需要知道任何c,或c ++。咕噜咕噜?

优势:访问cpython,不像以下方法那么困难

弊:无法直接从 python 更改 java 对象的成员数据。有点间接,(jython是中间人)。

Java到C/C++通过JNI/JNA/SWIG到Python通过嵌入式解释器(也许使用BOOST库?

OMG这种方法不适合胆小的人。我可以告诉你,我花了很长时间才用一个体面的方法做到这一点。你想要这样做的主要原因是,你可以运行cpython代码,作为对你的java对象的完全控制。在决定尝试用python(像马一样)为java(像黑猩猩)面包之前,需要考虑一些重大的事情。首先,如果您使解释器崩溃,那么您的程序就会熄灯!不要让我开始解决并发问题!此外,还有分配的锅炉,我相信我已经找到了最好的配置来最小化这个锅炉,但它仍然是分配的!那么该怎么做呢:考虑一下C++是你的中间人,你的对象实际上是c ++对象!很好,你现在知道了。只需像cpp而不是java一样编写您的对象,就像您的程序一样,其中包含要从两个世界访问的数据。然后,您可以使用名为swig(http://www.swig.org/Doc1.3/Java.html)的包装器生成器来使java可以访问它,并编译一个dll,您可以在java中调用System.load(此处为dll名称)。首先让它工作,然后继续困难的部分!要获得python,您需要嵌入一个解释器。首先,我建议做一些hello解释器程序或本教程在C / C中嵌入python。一旦你有了这个工作,是时候让马和猴子跳舞了!你可以通过 [boost][3] 将 c++ 对象发送到 python。我知道我没有给你鱼,只是告诉你在哪里找到鱼。编译时要注意的一些指针。

当你编译boost时,你需要编译一个共享库。你需要包含并链接到你需要的东西从jdk,即jawt.lib,jvm.lib,(你还需要客户端jvm.dll在你的路径上启动应用程序)以及python27.lib或其他任何东西和boost_python-vc100-mt-1_55.lib。然后包括Python/include,jdk/include,boost,只使用共享库(dlls),否则boost有眼泪。是的,我知道。有很多方法可以让它变酸。因此,请确保您逐个块地完成每件事。然后把它们放在一起。