在 Java 中调用 Python?

2025-01-06 08:32:00
admin
原创
169
摘要:问题描述:我想知道是否可以使用 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大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1579  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1355  
  信创产品在政府采购中的占比分析随着信息技术的飞速发展以及国家对信息安全重视程度的不断提高,信创产业应运而生并迅速崛起。信创,即信息技术应用创新,旨在实现信息技术领域的自主可控,减少对国外技术的依赖,保障国家信息安全。政府采购作为推动信创产业发展的重要力量,其对信创产品的采购占比情况备受关注。这不仅关系到信创产业的发展前...
信创和国产化的区别   8  
  信创,即信息技术应用创新产业,旨在实现信息技术领域的自主可控,摆脱对国外技术的依赖。近年来,国货国用信创发展势头迅猛,在诸多领域取得了显著成果。这一发展趋势对科技创新产生了深远的推动作用,不仅提升了我国在信息技术领域的自主创新能力,还为经济社会的数字化转型提供了坚实支撑。信创推动核心技术突破信创产业的发展促使企业和科研...
信创工作   9  
  信创技术,即信息技术应用创新产业,旨在实现信息技术领域的自主可控与安全可靠。近年来,信创技术发展迅猛,对中小企业产生了深远的影响,带来了诸多不可忽视的价值。在数字化转型的浪潮中,中小企业面临着激烈的市场竞争和复杂多变的环境,信创技术的出现为它们提供了新的发展机遇和支撑。信创技术对中小企业的影响技术架构变革信创技术促使中...
信创国产化   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用