从Java调用python函数的不同/更好的方法

时间:2016-09-09 11:16:18

标签: java python jython jpype py4j

我是python的新手,我试图从java调用python的函数。

我的主要要求是:

  • 调用应该是透明的,因为它不应该只需要修改.py文件就可以从java调用它。我可能会给它任何包含一些函数的python文件。我应该能够调用这些函数中的任何一个,而无需修改.py文件。
  • 我希望能够发送两种原始类型(intStringfloats等)或非原始类型(HashMap,{{1从java到python函数并从python到java接收返回的对象(可能是原始类型或非原始类型)。我也使用pandas DataFrame和numpy ndarray,因此也希望能够从java发送和接收相应的对象。
  • 最好想要坚持CPython而不是Jython,因为我可能需要使用Jython中可能没有的新库。

我在网上找到了几个选项。很少有人:

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

    py1.py

    .py

    JythonTest.groovy

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

    我完全能够满足我的需求。但它不是CPython。

  • 使用ScriptEngine :这与PythonInterpreter非常相似。但它的Jython再次出现。此外,与PythonInterpreter不同,我们无法使用Jython 2.5+并且无法直接访问PyObjects。所以这个选项可以很好地关闭。

  • 使用py4j :无法找到与Jython PythonInterpreter
  • 一样最小的示例
  • 使用java2python 。但是not much information is given关于从java调用python以便我可以得出结论是否可以满足我的上述要求。任何人都可以对此有所了解吗?更具体地说,如果我们可以编写与Jython PythonInterpreter中的代码一样小的代码。
  • 使用JPype :但是在快速浏览后,我觉得我无法像Jython PythonInterpreter那样编写最小代码。我觉得这个项目有点不发展。是吗?

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

2 个答案:

答案 0 :(得分:2)

@ Mahesha999,关于坚持使用CPython的功能,从您的最后评论开始,现在看来这很重要:

Jep是一个很好的选择,它能够运行使用对本地调用的python代码,例如您提到的熊猫。

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

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

您可以使用Jep.getValue(String pythonVariableName, Class clazz)

从执行的python代码中返回Java值。

例如

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应用程序中,到目前为止,它仍然有效。

答案 1 :(得分:1)

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

有时你想要的答案是不可用的!