用Java调用Python?

时间:2012-01-17 17:10:29

标签: java python jython

我想知道是否可以使用jython从java代码调用python函数,还是仅用于从python调用java代码?

12 个答案:

答案 0 :(得分:89)

Jython:Java平台的Python - 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);

答案 1 :(得分:53)

嘿,我以为即使已经迟到,我也会回答这个问题。我认为首先要考虑一些重要的事情,你希望有多强大的java和python之间的链接。

首先您是否只想调用函数或者您是否真的想要python代码来更改java对象中的数据?这是非常重要的。如果您只想调用带或不带参数的python代码,那么这并不是很困难。如果你的参数是原始的,那就更容易了。但是如果你想在python中有java类实现成员函数,这会改变java对象的数据,那么这不是那么容易或直接。

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

所以我使用了以下方法,并将它们从易到难的列出:

Java to Jython

优点:轻松简单。实际引用java对象

缺点:没有CPython,非常慢!

来自java的Jython非常简单,如果这真的足够那么好。然而它非常慢,没有cpython!如果没有cpython,生活是否值得生活我不这么认为!您可以轻松地使用python代码为您的java对象实现您的成员函数。

通过Pyro从Jython到CPython的Java

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

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

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

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

OMG这种方法不适合胆小的人。而且我可以告诉你,用一种不错的方法实现这一目标需要很长时间。你想要这样做的主要原因是你可以运行cpython代码,它完全控制你的java对象。在决定尝试使用python(就像一匹马)来尝试和java(就像一只黑猩猩)一样,需要考虑一些重要的事情。首先,如果你让翻译失败,你的节目就会熄灯!并没有让我开始处理并发问题!此外,还有分配锅炉,我相信我找到了最好的配置,以尽量减少这个锅炉,但它仍然是分配!那么如何解决这个问题: 考虑到C ++是你的中间人,你的对象实际上是c ++对象!好,你现在知道了。只需将您的对象编写为cpp中的程序,而不是使用您希望从两个世界访问的数据。然后你可以使用名为swig(http://www.swig.org/Doc1.3/Java.html)的包装器生成器使java可以访问它并编译一个你在java中调用System.load(这里是dll名称)的dll。首先让这个工作,然后继续努力! 要进入python,您需要嵌入一个解释器。首先,我建议做一些你好的翻译程序或本教程Embedding python in 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有一个teary。我知道,是的。有很多方法可以解决这个问题。因此,请确保逐块完成每件事。然后把它们放在一起。

答案 2 :(得分:8)

在java中使用python代码并不聪明。用烧瓶或其他Web框架包装您的python代码,使其成为微服务。让你的java程序能够调用这个微服务(例如通过REST)。

相信我,这很简单,可以为您节省大量的问题。代码松散耦合,因此可扩展。

答案 3 :(得分:8)

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

答案 4 :(得分:7)

这里有一个库,可以让你编写一次python脚本并决定在运行时使用哪种集成方法(Jython,CPython / PyPy通过Jep和Py4j):

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

由于每种方法都有其自身的优点/缺点,如链接中所述。

答案 5 :(得分:5)

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

答案 6 :(得分:4)

这取决于你的python函数是什么意思?如果它们是用cpython编写的,你不能直接调用它们,你将不得不使用JNI,但如果它们是用Jython编写的,你可以很容易地用java调用它们,因为jython最终生成java字节码。

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

how to use Python interpreter in Java.

答案 7 :(得分:4)

根据您的要求,XML-RPC等选项可能很有用,可用于以支持协议的任何语言虚拟远程调用功能。

答案 8 :(得分:3)

您可以使用Java Native Interface

从java调用任何语言

答案 9 :(得分:2)

Jython有一些限制:

  

有许多不同之处。首先,Jython程序不能使用CPython   用C语言编写的扩展模块。这些模块通常都带有文件   扩展名.so,.pyd或.dll。如果你想使用这样的模块,你应该看看   用纯Python或Java编写的等价物。虽然这是技术上的   支持这种扩展是可行的 - IronPython这样做 - 没有计划   在Jython中这样做。

Distributing my Python scripts as JAR files with Jython?

您可以使用Runtime或ProcessBuilder从Java调用python脚本(或bash或Perl脚本)并将输出传递回Java:

Running a bash shell script in java

Running Command Line in Java

java runtime.getruntime() getting output from executing a command line program

答案 10 :(得分:0)

This对当前选项进行了很好的概述。其中一些在其他答案中被命名。在Jython决定实现Python 3.x之前,Jython才可用,并且许多其他项目都从python端开始并希望访问Java。但是,还有一些选项可以命名尚未命名的名称:gRPC

答案 11 :(得分:0)

我有类似的需求,我认为对我来说最好的解决方案是 thrift(也是一个 rpc 解决方案),现在刚刚运行测试成功通过,并且可以使用 thrift-generator 从 java 接口生成 thrift 文件,然后从thrift文件中生成python文件和java客户端文件