在Java中调用Python?


Answers:


100

Jython:适用于Java平台的Python- http ://www.jython.org/index.html

您可以使用Jython从Java代码轻松调用python函数。只要您的python代码本身在jython下运行,即不使用某些不受支持的c扩展名。

如果这对您有用,那肯定是您可以获得的最简单的解决方案。否则,您可以使用org.python.util.PythonInterpreter新的Java6解释器支持。

我的脑海中有一个简单的例子-但我希望它可以工作:(为简便起见,没有进行错误检查)

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);

我已经安装了JYthon,或者我假设已经安装了JYthon,但我一直尝试运行您概述的代码,但突出显示为错误。Jython的安装是否需要转到python或java文件夹中的特定文件夹?
沙哈卜2012年

2
没有任何错误,我很难将Jython集成到Netbeans中
Shahab 2012年

如果没有错误,它将起作用,因此显然不是这样;)“ Error”并不意味着运行时错误,也可能是编译错误。
Voo 2012年

我不好,这是该词的错误使用。我试图将jython.jar添加到我的项目和netbeans中。我想通了
Shahab 2012年

1
Python 2寿命终止于1.1.2020,而Jython仅支持Python 2.7。所以没有Jython基本上死了。最佳(最简单)的选择是Jep lib
garyee,

62

嘿,我想我会输入我的答案,尽管已经很晚了。我想首先要考虑一些重要的事情,即您希望在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对象实现成员函数。

通过Pyro从Java到Jython到CPython

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

优点:访问cpython,不像以下方法那样困难

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

通过JNI / JNA / SWIG将Java转换为C / C ++,通过嵌入式解释器转换为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解释程序或本教程 python嵌入C / C中。一旦完成这项工作,就该让马和猴子跳舞了!您可以通过[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,并且仅使用共享库(dll),否则boost有眼泪。是的,我知道。有很多方法可以解决此问题。因此,请确保您一步一步地完成每件事。然后将它们放在一起。


2
这里是一个库,可让您一次编写python脚本并决定在运行时使用哪种集成方法(Jython,通过Jep的CPython和Py4j):github.com/subes/invesdwin-context-python由于每种方法都有其自身的优点/缺点

@subes这个项目看起来很棒,我前一阵子写的。我鼓励您写一个我会赞成的答案。我不喜欢最重要的答案哈哈,因为我认为它在Google搜索之外没有提供很多有用的信息。
Snickers3192'6

我创建了一个单独的答案
6

3
这个答案闻起来“应该是被接受的答案”还是仅仅是我?;-)
Mauricio Gracia Gutierrez

18

在Java中包含python代码并不明智。用flask或其他Web框架包装您的python代码,使其成为微服务。使您的Java程序能够调用此微服务(例如,通过REST)。

相信我,这很简单,可以为您节省很多问题。而且代码是松散耦合的,因此它们是可伸缩的。

于2020年3月24日更新:根据@stx的评论,上述方法不适用于客户端和服务器之间的海量数据传输。这是我推荐的另一种方法:使用Rust连接Python和Java(也可以使用C / C ++)。 https://medium.com/@shmulikamar/https-medium-com-shmulikamar-connecting-python-and-java-with-rust-11c256a1dfb0


+1,但是在两端创建和解析来回消息的额外性能和通信开销又如何呢?
STX

是的,这需要使用最少的输入/输出定义一个api接口。在网络上的客户端/服务器之间拥有大量数据传输器并不明智。如果您不能定义这样的接口,则此设计方法不适合。
胡佩明

10

有几个答案提到您可以使用JNI或JNA来访问cpython,但我不建议您从头开始,因为已经有了用于从java访问cpython的开源库。例如:



6

这取决于您对python函数的含义是什么?如果它们是用cpython编写的,则不能直接调用它们,则必须使用JNI,但是如果它们是用Jython编写的可以轻松地从Java调用它们,因为jython最终会生成Java字节码。

现在,当我说用cpython或jython编写时,这没有多大意义,因为python是python,并且除非您使用依赖于cpython或java的特定库,否则大多数代码都可以在两种实现上运行。

请参阅此处如何在Java中使用Python解释器。


5

根据您的要求,诸如XML-RPC之类的选项可能会很有用,它可以用于虚拟地以任何支持协议的语言远程调用函数。


5

GraalVM是一个不错的选择。我已经完成了与GraalVM的Java + Javascript组合用于微服务设计(具有Javascript反射功能的Java)。他们最近增加了对python的支持,我想尝试一下,尤其是多年来这些社区的规模。


4

您可以使用Java Native Interface从Java调用任何语言


6
可以从c调用本身的任何语言。好的python可以,但是Jython实际上是一个简单得多的解决方案(或在j6 +中使用PyInterpreter)。编写代码从c调用python函数并不是那么简单。
Voo 2012年

2

Jython有一些限制:

有许多差异。首先,Jython程序不能使用用C编写的CPython扩展模块。这些模块通常具有扩展名为.so,.pyd或.dll的文件。如果要使用这样的模块,则应寻找用纯Python或Java编写的等效模块。尽管在技术上支持此类扩展是可行的-IronPython这样做-在Jython中尚无计划这样做。

使用Jython将我的Python脚本作为JAR文件分发吗?

您只需使用Runtime或ProcessBuilder从Java调用python脚本(或bash或Perl脚本),然后将输出传递回Java:

在Java中运行bash shell脚本

在Java中运行命令行

java runtime.getruntime()从执行命令行程序获取输出


0

这样可以很好地概述当前的选项。其中一些在其他答案中被命名。在他们决定实现Python 3.x之前,Jython不可用,并且许多其他项目都来自python方面并希望访问java。但是,还有一些选项可以命名尚未命名的名称:gRPC

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.