gpt4 book ai didi

java - 只需导入一次即可通过 Java 运行 Python 脚本

转载 作者:行者123 更新时间:2023-12-01 14:10:24 24 4
gpt4 key购买 nike

2020 年 4 月更新 :我已经接受了下面的答案,因为它为我的问题提出了一个非常好的和简单的解决方案,但我的代码从未起作用!如果有人已经建立了类似的东西,请联系我!

我有一个简单的脚本 my-script.py使用在 Python 中编写的特定库可以非常快速地进行一些计算:

import sys
import special-library

def fun(x):
do something

fun(sys.argv[1])

在我的 Java代码,我在代码的不同部分多次使用/调用这个脚本,使用 ProcessBuilder方法,这意味着我只需运行命令 python my-script.py argument .
这意味着每次调用这个脚本时,我都必须执行 import最多的命令 耗时这里面的事情(计算部分实际上更快)。

有没有解决办法 所以我只调用一次导入 ?我看了一点 Jython - 是否可以编写一个类或一些可以启动并导入一次然后每次我想做计算部分时调用它的函数( fun )?有没有人做过类似的事情或对此有任何其他解决方案?

实现的第一次尝试

我试图编写一个“管道”Java 类,它将执行一次 python 脚本。现在脚本从标准输入中连续读取,当它获得输入时 argument ,它进行计算并返回结果:

import sys
import special-library

def fun(x):
do something
print('END')

for arg in sys.stdin:
fun(arg)

当我从命令行测试它并为它提供输入参数时,这当然有效。

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;
}
}

所以,我所做的是在我的代码的初始化部分的某个地方,我有这个简单的行来启动这个过程:

new MPBNPythonScriptExecuter();

后来当我想得到一些结果时,我使用:
String arg = "something"
Arraylist<String> res = PythonScriptExecuter.getResults(arg);

整个事情都卡在从脚本中读取输出的行上:
while (!(line = pythonToJavaReader.readLine()).equals("END"))

任何想法这里出了什么问题?

最佳答案

您可以使用管道在 java 和 Python 之间进行通信。

你像现在一样运行你的 Python(没有命令行参数)

Python脚本

你在 python 中编写了一个无限循环,它将

  • 从中读取数据
    标准输入(它将是函数的参数)
  • 你调用你的函数
  • 你把答案写到标准输出

  • java
  • 写一个向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()));
    }

    关于java - 只需导入一次即可通过 Java 运行 Python 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61070674/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com