从 Java 调用 python 函数的不同/更好的方法
Different / better approaches for calling python function from Java
我是 python 的新手,正在尝试从 java 调用 python 的函数。
我的主要要求是:
- 调用应该是透明的,因为它不需要修改
.py
文件就可以从 java 调用它。我可能会得到任何 python 文件,里面有一些函数。我应该能够调用这些函数中的任何一个而无需修改 .py
文件。
- 我希望能够发送原始类型(
int
、String
、floats
等)或非原始类型(HashMap
、ArrayList
) 从 java 到 python 函数并接收从 python 到 java 返回的对象(可能是原始类型或非原始类型)。我也在使用 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. But not much information is given关于从java调用python这样我就可以断定是否可以满足我的上述要求。谁能对此有更多的了解?更具体地说,如果我们可以编写与 Jython PythonInterpreter 中的代码一样最少的代码。
- 使用JPype:但是在快速浏览之后,我觉得我将无法像使用 Jython PythonInterpreter 那样编写尽可能少的代码。我也觉得这个项目有点不在开发中。是吗?
如果我正确理解了上述所有方法,那么 Jython PythonInterpreter 似乎是最佳选择。我是不是在把握的过程中犯了错误?还有其他更好的选择吗?
这个问题目前没有答案。使用 CPython 依赖于 Python 字节码的执行,这反过来又要求将 Python 解释器嵌入到执行环境中。由于没有 Java 运行时带有嵌入式 Python 解释器,因此看起来 Jython 确实是最佳答案。
有时您想要的答案是找不到的!
@Mahesha999,关于坚持使用 CPython 的能力,从你上一条评论来看现在这似乎很重要:
Jep 是一个很好的选择,它能够 运行 python 调用本机的代码,例如您提到的 pandas。
您需要编写一些包装代码,因为 Jep 仅在最常用的类型之间实现 Java 和 Python 之间的自动转换,而 pandas.DataFrame
不是。
但是,如果您的用例不是很复杂,您可以通过在数据帧实例上调用 DataFrame.values
来将 pandas 对象作为 numpy.NDArray
对象访问,并且 Jep 实现转换为Java class 它为 NDArray 嵌入。
您可以使用 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 应用程序中,到目前为止它可以工作。
我是 python 的新手,正在尝试从 java 调用 python 的函数。
我的主要要求是:
- 调用应该是透明的,因为它不需要修改
.py
文件就可以从 java 调用它。我可能会得到任何 python 文件,里面有一些函数。我应该能够调用这些函数中的任何一个而无需修改.py
文件。 - 我希望能够发送原始类型(
int
、String
、floats
等)或非原始类型(HashMap
、ArrayList
) 从 java 到 python 函数并接收从 python 到 java 返回的对象(可能是原始类型或非原始类型)。我也在使用 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. But not much information is given关于从java调用python这样我就可以断定是否可以满足我的上述要求。谁能对此有更多的了解?更具体地说,如果我们可以编写与 Jython PythonInterpreter 中的代码一样最少的代码。
- 使用JPype:但是在快速浏览之后,我觉得我将无法像使用 Jython PythonInterpreter 那样编写尽可能少的代码。我也觉得这个项目有点不在开发中。是吗?
如果我正确理解了上述所有方法,那么 Jython PythonInterpreter 似乎是最佳选择。我是不是在把握的过程中犯了错误?还有其他更好的选择吗?
这个问题目前没有答案。使用 CPython 依赖于 Python 字节码的执行,这反过来又要求将 Python 解释器嵌入到执行环境中。由于没有 Java 运行时带有嵌入式 Python 解释器,因此看起来 Jython 确实是最佳答案。
有时您想要的答案是找不到的!
@Mahesha999,关于坚持使用 CPython 的能力,从你上一条评论来看现在这似乎很重要:
Jep 是一个很好的选择,它能够 运行 python 调用本机的代码,例如您提到的 pandas。
您需要编写一些包装代码,因为 Jep 仅在最常用的类型之间实现 Java 和 Python 之间的自动转换,而 pandas.DataFrame
不是。
但是,如果您的用例不是很复杂,您可以通过在数据帧实例上调用 DataFrame.values
来将 pandas 对象作为 numpy.NDArray
对象访问,并且 Jep 实现转换为Java class 它为 NDArray 嵌入。
您可以使用 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 应用程序中,到目前为止它可以工作。