【问题标题】:Importing Java class into a python project将Java类导入python项目
【发布时间】:2026-01-03 05:10:01
【问题描述】:

我一直在尝试找到一种将 Java-ml 导入我的 python 项目的方法。我的 jar 文件与我的项目位于同一路径中。

我想将它用于 kmeans 聚类,因为它允许我更改距离度量。我想知道是否通过你们中的一个建议的实现,我是否能够将不同的 java 类作为函数的参数传递?

我尝试使用:

import sys

sys.path.append(r"C:\Users\X\Desktop\X\javaml-0.1.7\javaml-0.1.7.jar")

import net.sf.javaml as jml

test = jml.clustering.Kmeans()

我考虑过使用 jython,但我不确定它是如何工作的,并且我是否可以继续使用 idle 以及是否需要重新编程我的项目也不清楚。

最后我考虑过使用 PyJNIus,但它根本不起作用。

【问题讨论】:

  • 使用 PyJNIus 是一个很好的方法。我建议调试你的问题。还有其他库可以让你以类似的方式调用 java 代码。

标签: java python cross-platform multilingual cross-language


【解决方案1】:

简而言之,您不能在 CPython 解释器中本地运行 Java 代码。

首先,Python 只是语言规范的名称。如果您使用操作系统提供的 Python(或从 Python 官方网站下载),那么您使用的是 CPython。 CPython 没有解释 Java 代码的能力。

但是,正如您所提到的,有一个用于 JVM 的 Python 实现,称为 Jython。 Jython 是在 JVM 上运行的 Python 实现,因此可以与 Java 模块交互。但是,很少有人使用 Jython,因此您需要靠自己来确保一切正常运行。您不需要重新编写您的原始 Python 代码(因为 Jython 可以解释 Python 2.x),但并非所有库(例如 numpy)都将受支持。

最后,我认为您需要更好地理解 K-Means 算法,因为该算法是根据欧几里得距离隐式定义的。使用任何其他距离度量将不再被视为 K-Means,并且可能会影响算法的收敛性。请参阅here 了解更多信息。


同样,您不能在 CPython 解释器中本地运行 Java 代码。当然,有各种第三方库可以处理 Java 和 Python 之间的数据编组。但是,我坚持我的观点,对于这个特定的用例,您可能会更好地使用原生 Python 库(类似于 Scikit-Learn 中的 K-Medoid)。在我看来,尝试调用 Java 以及所有相关的开销对于这个问题来说太过分了。

【讨论】:

  • 感谢您的回复,但是我的代码在 Python 3 中,而 Jython 会要求我将其全部移植到 Python 2,您确定我不能调用 JVM 来执行此功能吗?我知道当我在 python 中使用斯坦福 POS 标记器时,它总是从 python 3 调用 jvm,它能够运行 java 类。
  • 根据您的代码内容,Python 2 和 Python 3 可能实际上不需要额外的代码。两个版本之间有非常显着的重叠。其次,当您说调用 JVM 时,您的意思是像子进程调用一样吗?因为这显然是可能的,尽管在 Python 和 Java 之间编组数据可能会很困难。
  • 我的数据,当以kmeans输入时,都是列表形式,所以理论上对数据进行编组应该不会太难。似乎他们确实使用了子流程调用,就像他们在导入时一样 from subprocess import PIPE
  • 您实际上可以从 python 调用 java 代码,使用例如PyJNIus 正如 OP 所建议的那样。但是,您不能像给出的示例中那样使用 python 导入语句导入它(尽管使用适当的导入钩子可能是可能的)。
  • @inclement 不,您不能在 Python 中运行 Java 代码,如 OP 所示。如果您使用第三方库,您可能能够与 Java 交互,但您实际上只是在 Java/Python 边界之间编组数据。在 PyJNIus 的情况下,数据通过 JNI 接口进行编组,但最终它只是进行子进程调用的二进制方法。它们不存在于同一个进程中,您并没有真正运行 Java - 您只是使用处理编组的包装类。
【解决方案2】:

要直接“回答”您的问题,如果您只想导入 Java 类,Jython 将是您的最佳选择。 Jython 非常努力地尽可能与 Python 2.x 兼容并且做得很好。所以你不必花太多时间重写代码。只需简单地用 Jython 运行它,看看会发生什么,然后修改什么中断。

现在是 Python 答案:D。您可能希望将scikit 用于本机实现。它肯定比在 Jython 中运行任何东西都要快。

更新

我认为Py4J 模块就是您正在寻找的。它通过在您的 Java 代码中运行服务器来工作,Python 代码将与 Java 服务器进行通信。 “Py4J”唯一的好处是它为你提供了样板代码。您可以非常轻松地设置自己的客户端/服务器,而无需额外的模块。但是我仍然认为与 Python 的原生模块相比,它不是一个更好的选择。

参考文献

How to import Java class w/ Jython

Scikit - K-Means

【讨论】:

  • 感谢您的回复,但是我的代码在 Python 3 中,而 Jython 需要我将其全部移植到 Python 2,您确定我不能调用 JVM 来执行此功能吗?我知道当我在 python 中使用斯坦福 POS 标记器时,它总是从 python 3 调用 jvm,它能够运行 java 类。
  • Jython 的常见问题、重载方法以及如何处理它们 - *.com/questions/21329491/…
  • @benjrei 它可能涉及某种套接字/IP 桥接,斯坦福 POS 标记器的网站提到了 nltk,也许你可以使用它来代替?
  • @benjrei “call the JVM”是什么意思?
  • @notorious 他们使用带有管道的子流程模块。在源文件中它有导入from subprocess import PIPE