在 Java 中调用 Python?

2025-01-06 08:32:00
admin
原创
168
摘要:问题描述:我想知道是否可以使用 Jython 从 Java 代码调用 Python 函数,或者只能从 Python 调用 Java 代码?解决方案 1:Jython:用于 Java 平台的 Python - http://www.jython.org/index.html您可以使用 Jython 轻松地从 J...

问题描述:

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


解决方案 1:

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
sys.path.append('pathToModules if they are not there by default')
import 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 如此酷的原因!虽然具有如此高的抽象性,但在需要时可以访问 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++,再通过嵌入式解释器将 Java 转换为 Python(也许使用 BOOST 库?)

天哪,这个方法不适合胆小的人。我可以告诉你,我花了很长时间才找到一个像样的方法来实现这一点。你想这样做的主要原因是,这样你就可以运行 CPython 代码,完全控制你的 java 对象。在决定尝试将 Java(就像一只黑猩猩)与 Python(就像一匹马)杂交之前,需要考虑一些重要的事情。首先,如果你让解释器崩溃,那么你的程序就完蛋了!不要让我开始讨论并发问题!此外,还有很多锅炉,我相信我已经找到了最小化这个锅炉的最佳配置,但仍然很多!那么如何做到这一点:考虑 C++ 是你的中间人,你的对象实际上是 C++ 对象!很高兴你现在知道了。只需编写你的对象,就好像你的程序是用 C++ 而不是 Java 编写的,使用你想从两个世界访问的数据。然后,你可以使用名为SWIG 的包装器生成器使其可供 java 访问,并编译一个你在 Java 中调用 () 的 dll System.load(dllNameHere)。先让它运行起来,然后再开始最难的部分!要使用 Python,您需要嵌入一个解释器。首先,我建议做一些 hello 解释器程序或本教程在 C/C 中嵌入 Python。一旦您让它运行起来,就该让马和猴子跳舞了!您可以通过 boost 将您的 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 会很麻烦。是的,我知道。有很多方法可能会出错。因此,请确保您逐块完成每件事。然后将它们放在一起。

解决方案 3:

在 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

解决方案 4:

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

  • 杰普

  • 日元

解决方案 5:

GraalVM是个不错的选择。我曾使用 GraalVM 进行 Java+Javascript 组合微服务设计(Java 和 Javascript 反射)。他们最近添加了对 Python 的支持,我会尝试一下,尤其是考虑到多年来它的社区发展如此之大。

2021 年 6 月更新

https://www.graalvm.org/reference-manual/python/

GraalVM 提供兼容 Python 3.8 的运行时。GraalVM Python 运行时的主要目标是支持 SciPy 及其组成库,以及与丰富的 Python 生态系统中的其他数据科学和机器学习库配合使用。目前,Python 运行时可供实验和好奇的最终用户使用。

解决方案 6:

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

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

因为每种方法都有其优点/缺点,如链接中所述。

(3 个模块:jep、Py4J、jython)

解决方案 7:

这取决于你所说的 python 函数是什么意思?如果它们是用cpython编写的,你就不能直接调用它们,而必须使用JNI ,但如果它们是用Jython编写的,你可以轻松地从 java 调用它们,因为 jython 最终会生成 java 字节码。

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

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

解决方案 8:

根据您的要求,像XML-RPC这样的选项可能会有用,它可以用来远程调用几乎任何支持该协议的语言中的函数。

解决方案 9:

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() 获取执行命令行程序的输出

解决方案 10:

您可以使用Java 本机接口从 Java 调用任何语言

解决方案 11:

这很好地概述了当前的选项。其中一些在其他答案中被提及。在他们决定不实现 Python 3 之前,Jython 不可用。许多其他项目来自 Python 方面,并希望访问 Java。但仍有几个选项,命名一些尚未命名的东西:gRPC

解决方案 12:

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

解决方案 13:

在从 Python 到 Java 的数据交换方面,我们可以将其作为休息服务并以 XML 或 Json 格式交换数据,但有时我们需要调用使用 Python 轻松创建的自动脚本以在 Java 文件中调用。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用