【问题标题】:Invoke Python modules from Java从 Java 调用 Python 模块
【发布时间】:2026-02-15 09:05:01
【问题描述】:

我有一个用 C 语言编写的图形库的 Python 接口 - igraph(库的名称)。我的需要是从 Java 代码中调用与此图形库有关的 python 模块。就像这样,库的核心是在 c 中。该内核已导入 Python,并且内核中嵌入的函数的接口在 Python 中可用。我项目的其余代码是用 Java 编写的,因此我也想用 Java 调用图形函数。 Jython - 允许您在 Java 中调用 python 模块是一个选项。我继续尝试 Jython 发现它在我的情况下不起作用,因为核心代码在 C 中并且 Jython 不支持在 python 中作为 ac dll 导入的任何内容代码。我也想过选择直接在c中调用图形例程的方法。那是不通过 Python 代码。我假设一定有一些东西可以让你从 Java 中调用 c 代码,但我在 C 语言方面做得不好,因此我没有去做。 我最后的手段似乎是使用 Java 从命令行执行 Python 解释器。但那是一种肮脏和无耻的行为。此外,为了处理 Python 代码产生的结果,我必须将结果写入文件并在 java 中读回。再次肮脏的方式。 有什么可以建议我的吗?感谢每一位付出的时间。


感谢伊格尔的回答。我看过了。乍一看,它似乎只是在调用 python 脚本。

Jep jep = new Jep(false, SCRIPT_PATH, cl);
jep.set("query", query);
jep.runScript(SCRIPT_PATH + file);
jep.close();

这和我们在命令行中通过 Java 代码调用 python 解释器的做法非常相似吗?

Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("python test.py");

关心的是如何使用 Python 脚本生成的结果。天真的方法是将它们写入文件并用 Java 读回。我正在寻找一种更智能的方法。无论如何感谢您的建议。

【问题讨论】:

    标签: java python ipc


    【解决方案1】:

    从未尝试过。但我最近在project named Jeppstumbled,您可能会感兴趣。

    Jepp 在 Java 中嵌入了 CPython。在多线程环境中使用是安全的,速度非常快,稳定性是主要功能和目标。

    【讨论】:

      【解决方案2】:

      如果你想从 Java 调用 C 函数,JNA (Java Native Access) 可能是要走的路。 JNA 允许您调用本机库中的函数,而无需编写 C 胶水代码(就像使用 JNI 时必须那样),并自动在 Java 和 C 中的原始数据类型之间进行映射。一个简单的示例可能如下所示:

      import com.sun.jna.Native;
      import com.sun.jna.Library;
      
      public class PrintfWrapper {
          public interface CLibrary extends Library {
              CLibrary INSTANCE = (CLibrary)Native.loadLibrary("c", CLibrary.class);
              void printf(String formatString, Object... args);
          }
      
          public static void main(String[] args) {
              CLibrary.INSTANCE.printf("Hello, world\n");
          }
      }
      

      但是,使用 igraph 会使事情变得复杂,因为 igraph 使用许多无法直接映射到 Java 对应物的数据结构。有一个名为 JNAerator 的项目应该能够从 igraph 的头文件生成 JNA 源,但我从未尝试过,结果可能仍需要一些手动调整。

      另请注意,Java interface for igraph 正在缓慢而稳定地开发,它可能会在几个月左右变得有用。

      【讨论】:

        【解决方案3】:

        您可以使用 jep.getValue() 从脚本的全局字典中检索值。

        关于 Python 中的作用域级别有一些警告,因此大多数人发现将 Java 类传递给 Python 并在 Python 中在该实例中设置返回值更清楚。脚本完成后,Java 代码就会有结果。

        例如:

        ==>Java

        class ReturnValueClass {
           public int scriptResult;
        };
        ReturnValueClass value = new ReturnValueClass();
        jep.set("retval", value);
        

        ==>Python

        # do something
        pass
        # write the return value
        retval.scriptResult = some_python_value
        

        ==>Java

        System.out.println(value.scriptResult);
        

        希望对你有帮助,

        迈克(我写了 Jep)

        【讨论】: