Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Java调用python函数的不同/更好的方法_Java_Python_Jython_Jpype_Py4j - Fatal编程技术网

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

从Java调用python函数的不同/更好的方法,java,python,jython,jpype,py4j,Java,Python,Jython,Jpype,Py4j,我对python非常陌生,正在尝试从java调用python的函数 我的主要要求是: 调用应该是透明的,因为它不需要修改.py文件就可以从java调用它。我可能会得到任何包含一些函数的python文件。我应该能够调用这些函数中的任何一个,而无需修改.py文件 我希望能够将基本类型(int,String,floats等)或非基本类型(HashMap,ArrayList)的参数从java发送到python函数,并从python接收返回的对象(可能是基本类型或非基本类型)。我还使用pandas Da

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

我的主要要求是:

  • 调用应该是透明的,因为它不需要修改
    .py
    文件就可以从java调用它。我可能会得到任何包含一些函数的python文件。我应该能够调用这些函数中的任何一个,而无需修改
    .py
    文件
  • 我希望能够将基本类型(
    int
    String
    floats
    等)或非基本类型(
    HashMap
    ArrayList
    )的参数从java发送到python函数,并从python接收返回的对象(可能是基本类型或非基本类型)。我还使用pandas DataFrame和numpy ndarray,因此也希望能够向java发送和接收相应的对象
  • 我更希望坚持使用CPython而不是Jython,因为我可能需要使用Jython中可能没有的更新库
我在网上找到了几个选项。很少有人是:

  • 使用Jython的调用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

  • 使用:这与PythonInterpreter非常相似。但是它的Jython。此外,与PythonInterpreter不同,我们不能使用Jython2.5+并且不能直接访问Python对象。因此,这个选项可以很好地关闭

  • 使用:找不到与Jython Pythonterpreter一样简单的示例
  • 使用。但是关于从java调用python,我可以断定我的上述需求是否能够得到满足。有人能解释一下吗?更具体地说,如果我们可以编写与Jython PythonInterpreter中的代码一样少的代码
  • 使用:但是在快速浏览之后,我觉得我将无法像Jython Pythonterpreter那样编写最少的代码。我也觉得这个项目还没有开发出来。是吗

如果我正确理解了以上所有方法,那么Jython PythonInterpreter似乎是最好的选择。我在抓的时候犯过错误吗?还有其他更好的选择吗?

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


有时候你想要的答案根本就不存在

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

Jep是一个很好的选项,可以运行python代码,该代码使用对本机的调用,就像您提到的pandas一样

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

但是,如果您的用例不太复杂,您可以通过在DataFrame实例上调用
DataFrame.values
,以
numpy.NDArray
对象的形式访问pandas对象,并且Jep实现到它为NDArray嵌入的Java类的转换

您可以通过使用
Jep.getValue(字符串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应用程序中,到目前为止,它是可以工作的。

不完全相关,但是有什么特别的原因让你更喜欢使用CPython而不是Jython吗?在Java和CPython之间编组数据类型将更加困难,而Jython构建在JVM互操作之上应该更简单,也可能是因为我可能需要等待一些新的库在CPython中可用,但还没有出现,JythonI在我的用例中从来没有遇到过Jython的性能问题(当然,在您的用例中可能会有所不同)。库的可用性当然是一个潜在的问题,但是,除非您确定需要使用Jython无法使用的库,否则我认为使用它比使用CPython更容易。(这是我通常做的,因为我不知道有任何胶水库可以实现你需要的那种互操作)好吧,那么你和我的观点一样,PythonInterpreter是最好的方式吗?在我看来,是的。(除非,如前所述,您绝对需要使用CPython)我最近再次访问这个。我意识到我又错过了一个选项:。有什么要找的吗?似乎有必要使用jep来处理熊猫数据帧。此外,我们似乎无法使用jep从python获得java的返回值。是这样吗?另外,我在原始帖子中的要求也有了一些改变,因为我需要向java和python发送/接收pandas数据帧和numpy ndarray。