3

我对python很陌生,正在尝试从java调用python的函数。

我的主要要求是这些:

  • call 应该是透明的,从某种意义上说,它不应该.py仅仅为了能够从 java 调用它而需要修改文件。我可能会得到任何包含一些函数的 python 文件。我应该能够调用这些函数中的任何一个而不需要修改.py文件。
  • 我希望能够将原始类型(int,Stringfloats)或非原始类型(HashMap, ArrayList)的参数从 java 发送到 python 函数,并从 python 接收返回的对象(可能是原始类型或非原始类型)到爪哇。我也在使用 pandas DataFrame 和 numpy ndarray,因此也希望能够与 java 之间发送和接收相应的对象。
  • 愿意坚持使用 CPython 而不是 Jython,因为我可能需要使用 Jython 中可能不可用的较新库。

我在网上找到了几个选项。少数是:

  • 使用 Jython 的PythonInterpreter,我可以使用它调用 python 函数,而无需对.py脚本文件进行任何更改:

    py1.py

     def square2(list):
         squares = []
         for i in list:
             squares.append(i*i)
         return squares
    

    JythonTest.groovy

     import org.python.util.PythonInterpreter
     import org.python.core.*;
    
     class JythonTest
     {
          static main(def args)
          {
              PythonInterpreter pi = new PythonInterpreter()
              pi.exec("from py1 import square2")
              PyFunction pf = (PyFunction)pi.get("square2")
              println pf.__call__(new PyList([1,2,3,4]))[2]   //9
          }
     }
    

    我能够很好地满足我的需求。但它不是 CPython。

  • 使用ScriptEngine:这与 PythonInterpreter 非常相似。但反对它的 Jython。此外,与 PythonInterpreter 不同的是,我们不能使用 Jython 2.5+,也不能直接访问 PyObjects。所以这个选项可以很好的关闭。

  • 使用py4j:找不到与 Jython PythonInterpreter 一样最小的示例
  • 使用java2python。但是没有太多关于从java调用python的信息,所以我可以断定我的上述要求是否可以满足。任何人都可以对此有所了解吗?更具体地说,如果我们可以编写与 Jython PythonInterpreter 中的代码一样少的代码。
  • 使用JPype:但是在快速完成之后,我觉得我将无法像使用 Jython PythonInterpreter 那样编写最少的代码。我也觉得这个项目有点没有在开发中。是吗?

如果我正确理解了上述所有方法,那么 Jython PythonInterpreter 似乎是最佳选择。我在掌握它们时是否犯了错误?还有其他更好的选择吗?

4

2 回答 2

2

@ Mahesha999,关于坚持使用 CPython 的能力,从您上次的评论来看,这似乎很重要:

Jep 是一个很好的选择,它能够运行使用本地调用的 python 代码,比如你提到的 pandas。

您需要编写一些包装代码,因为 Jep 仅在最常用的类型之间实现 Java 和 Python 之间的自动转换,而事实pandas.DataFrame并非如此。

但是,如果您的用例不复杂,您可以numpy.NDArray通过调用DataFrame.values您的数据框实例来访问您的 pandas 对象作为对象,并且 Jep 实现到它为 NDArray 嵌入的 Java 类的转换。

您可以使用执行的 python 代码返回 Java 值Jep.getValue(String pythonVariableName, Class clazz)

例如

Jep jep = new Jep();
jep.eval("import my_script");
jep.eval("df = my_script.function_returning_a_dataframe()");
jep.eval("col = df.a_column.values");
NDArray myCol = jep.getValue("col", NDArray.class);

我在我用 Python 编写的一个项目中这样做,我需要将其作为插件集成到 Java 应用程序中,到目前为止它可以工作。

于 2018-10-12T11:47:09.743 回答
1

这个问题目前没有答案。使用 CPython 依赖于 Python 字节码的执行,这反过来又需要将 Python 解释器嵌入到执行环境中。由于没有 Java 运行时附带嵌入式 Python 解释器,因此 Jython 看起来确实是最好的答案。

有时您想要的答案不可用!

于 2016-11-03T08:19:02.777 回答