Joh*_*ohn 3 python java import jython
2020 年 4 月更新:我接受了下面的答案,因为它为我的问题提出了一个非常好的和简单的解决方案,但我的代码从未起作用!如果有人已经建立了类似的东西,请联系我!
我有一个简单的脚本my-script.py,它使用编写的特定库非常快速地进行一些计算Python:
import sys
import special-library
def fun(x):
do something
fun(sys.argv[1])
Run Code Online (Sandbox Code Playgroud)
在我的Java代码中,我在代码的不同部分多次使用/调用此脚本,使用该ProcessBuilder方法,这意味着我只需运行命令python my-script.py argument。这意味着每次调用这个脚本时,我都必须执行import其中最耗时的命令(计算部分实际上更快)。
有没有办法让我只调用一次导入?我看了一点Jython- 是否可以编写一个类或一些可以启动的东西并进行一次导入,然后每次我想做计算部分(fun)时调用它的函数?有没有人做过类似的事情或对此有任何其他解决方案?
我试图编写一个“管道”Java 类,它将执行一次 python 脚本。现在脚本从 stdin 连续读取,当它获得 input 时argument,它会进行计算并返回结果:
import sys
import special-library
def fun(x):
do something
print('END')
for arg in sys.stdin:
fun(arg)
Run Code Online (Sandbox Code Playgroud)
当我从命令行测试它并为其提供输入参数时,这当然有效。
Java类如下:
package my.package;
import java.io.*;
public class PythonScriptExecuter {
private static BufferedReader pythonToJavaReader;
private static PrintWriter javaToPythonWriter;
public PythonScriptExecuter() throws Exception {
String MPBNScriptFile = "fullPathToScriptFile";
ProcessBuilder pb = new ProcessBuilder("python", MPBNScriptFile);
pb.redirectErrorStream(true);
// Start script
Process p = pb.start();
pythonToJavaReader = getOutputReader(p); // from python to java
javaToPythonWriter = getInputWriter(p); // from java to python
}
// Python => Java
private static BufferedReader getOutputReader(Process p) {
return new BufferedReader(new InputStreamReader(p.getInputStream()));
}
// Java => Python
private static PrintWriter getInputWriter(Process p) {
return new PrintWriter(new OutputStreamWriter(p.getOutputStream()));
}
public static Arraylist<String> getResults(String argument) throws IOException {
// send argument to python script
javaToPythonWriter.println(argument);
//javaToPythonWriter.flush();
// get results back one by one
ArrayList<String> results = new ArrayList<>();
int count = 0;
String line;
while (!(line = pythonToJavaReader.readLine()).equals("END")) {
// process `line` string
results.add(line);
}
return results;
}
}
Run Code Online (Sandbox Code Playgroud)
所以,我所做的是在我代码的初始化部分的某个地方,我有这个简单的行来启动这个过程:
new MPBNPythonScriptExecuter();
Run Code Online (Sandbox Code Playgroud)
后来当我想得到一些结果时,我使用:
String arg = "something"
Arraylist<String> res = PythonScriptExecuter.getResults(arg);
Run Code Online (Sandbox Code Playgroud)
整个事情都挂在从脚本读取输出的行上:
while (!(line = pythonToJavaReader.readLine()).equals("END"))
Run Code Online (Sandbox Code Playgroud)
任何想法这里出了什么问题?
您可以使用管道在 java 和 Python 之间进行通信。
你像现在一样运行你的 Python(没有命令行参数)
Python脚本
你在 python 中编写了一个无限循环,它将
从标准输入读取数据(它将是您的函数参数)
你调用你的函数
你把答案写到标准输出
爪哇
写一个向python发送args的方法
将函数的 arg 写入管道
从管道中读取答案
你完成了。
这是一些片段
在这里你如何创建你的管
Process p = Runtime.getRuntime().exec(commande);
BufferedReader output = getOutput(p); //from python to java
BufferedReader error = getError(p); //from python to java
PrintWriter input = getInput(p); //from java to python
private static BufferedReader getOutput(Process p) {
return new BufferedReader(new InputStreamReader(p.getInputStream()));
}
private static BufferedReader getError(Process p) {
return new BufferedReader(new InputStreamReader(p.getErrorStream()));
}
private static PrintWriter getInput(Process p){
return new PrintWriter (new OutputStreamWriter(p.getOutputStream()));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
415 次 |
| 最近记录: |