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

问题描述 投票:3回答:2

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)时调用它的函数?有没有人做过类似的事情或对此有其他解决方案?

首次尝试实施

我试图编写一个'pipe'Java类,它将执行一次python脚本。现在,脚本从stdin连续读取,并在获得输入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"))

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

[2020年4月更新:我接受了下面的答案,因为它为我的问题提出了一个非常好的和简单的解决方案,但是我却没有代码能正常工作!如果有人已经建立了类似的东西...

java python import jython
2个回答
6
投票

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


0
投票

在您的Python脚本中尝试以下操作:

© www.soinside.com 2019 - 2024. All rights reserved.