【问题标题】:Java - How to call python classes using processbuilderJava - 如何使用 processbuilder 调用 python 类
【发布时间】:2017-08-30 06:46:48
【问题描述】:

如何从 java 调用和执行 python 类方法。我当前的 java 代码有效,但前提是我写:

if __name__ == '__main__':
    print("hello")

但是我想执行一个类方法,不管if __name__ == '__main__':

我要运行的示例 python 类方法:

class SECFileScraper:
    def __init__(self):
        self.counter = 5

    def tester_func(self):
        return "hello, this test works"

基本上我想在 java 中运行 SECFileScraper.tester_func()。

我的 Java 代码:

try {

            ProcessBuilder pb = new ProcessBuilder(Arrays.asList(
                    "python", pdfFileScraper));
            Process p = pb.start();

            BufferedReader bfr = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line = "";
            System.out.println("Running Python starts: " + line);
            int exitCode = p.waitFor();
            System.out.println("Exit Code : " + exitCode);
            line = bfr.readLine();
            System.out.println("First Line: " + line);
            while ((line = bfr.readLine()) != null) {
                System.out.println("Python Output: " + line);


            }

        } catch (Exception e) {
            e.printStackTrace();
        }

pdfFileScraper 是我的 python 脚本的文件路径。

我尝试过jython,但是我的python文件使用了pandas和sqlite3,使用jython无法实现。

【问题讨论】:

    标签: java python processbuilder


    【解决方案1】:

    所以如果我理解你的要求,你想在pdfFileScraper.py 中调用一个类方法。从 shell 执行此操作的基础类似于:

    scraper=path/to/pdfFileScraper.py
    dir_of_scraper=$(dirname $scraper)
    export PYTHONPATH=$dir_of_scraper
    python -c 'import pdfFileScraper; pdfFileScraper.ClassInScraper()'
    

    我们所做的是获取pdfFileScraper的目录,并将其添加到PYTHONPATH,然后我们运行python命令将pdfFileScraper文件作为一个模块导入,它暴露了类中的所有方法和类命名空间pdfFileScraper,然后构造一个类ClassInScraper()

    在java中,类似:

    import java.io.*;
    import java.util.*;
    
    public class RunFile {
        public static void main(String args[]) throws Exception {
            File f = new File(args[0]); // .py file (e.g. bob/script.py)
    
            String dir = f.getParent(); // dir of .py file
            String file = f.getName(); // name of .py file (script.py)
            String module = file.substring(0, file.lastIndexOf('.'));
            String command = "import " + module + "; " + module + "." + args[1];
            List<String> items = Arrays.asList("python", "-c", command);
            ProcessBuilder pb = new ProcessBuilder(items);
            Map<String, String> env = pb.environment();
            env.put("PYTHONPATH", dir);
            pb.redirectErrorStream();
            Process p = pb.start();
    
            BufferedReader bfr = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line = "";
            System.out.println("Running Python starts: " + line);
            int exitCode = p.waitFor();
            System.out.println("Exit Code : " + exitCode);
            line = bfr.readLine();
            System.out.println("First Line: " + line);
            while ((line = bfr.readLine()) != null) {
                System.out.println("Python Output: " + line);
            }
        }
    }
    

    【讨论】:

    • 它不输出任何东西。我得到的只是:Running Python starts: Exit Code : 0 First Line: null
    • ProcessBuilder 只能处理 printed 返回输出,因此返回字符串的行实际上不会显示任何可以解析的内容。您需要print "This test works" 才能获得所需的结果。如果你想直接与 python 对象交互,那么你将不得不使用像 mko 那样的解决方案——即在 VM 中加载一个 python 解释器并直接与之交互。
    【解决方案2】:

    您也可以通过 JNI 直接调用 Python lib。这样,您无需启动新进程,您可以在脚本调用之间共享上下文等。

    在这里查看示例:

    https://github.com/mkopsnc/keplerhacks/tree/master/python

    【讨论】:

      【解决方案3】:

      这是对我有用的 java 类。

      class PythonFileReader {
      private String path;
      private String fileName;
      private String methodName;
      
      PythonFileReader(String path, String fileName, String methodName) throws Exception {
          this.path = path;
          this.fileName = fileName;
          this.methodName = methodName;
          reader();
      }
      
      private void reader() throws Exception {
      
          StringBuilder input_result = new StringBuilder();
          StringBuilder output_result = new StringBuilder();
          StringBuilder error_result = new StringBuilder();
          String line;
      
          String module = fileName.substring(0, fileName.lastIndexOf('.'));
          String command = "import " + module + "; " + module + "." + module + "." + methodName;
          List<String> items = Arrays.asList("python", "-c", command);
      
          ProcessBuilder pb = new ProcessBuilder(items);
          pb.directory(new File(path));
          Process p = pb.start();
          BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
          BufferedReader out = new BufferedReader(new InputStreamReader(p.getInputStream()));
          BufferedReader error = new BufferedReader(new InputStreamReader(p.getErrorStream()));
      
          while ((line = in.readLine()) != null)
              input_result.append("\n").append(line);
          if (input_result.length() > 0)
              System.out.println(fileName + " : " + input_result);
      
          while ((line = out.readLine()) != null)
              output_result.append(" ").append(line);
          if (output_result.length() > 0)
              System.out.println("Output : " + output_result);
      
          while ((line = error.readLine()) != null)
              error_result.append(" ").append(line);
          if (error_result.length() > 0)
              System.out.println("Error : " + error_result);
      }}
      

      这就是你可以使用这个类的方式

      public static void main(String[] args) throws Exception {
      
          String path = "python/path/file";
          String pyFileName = "python_name.py";
          String methodeName = "test('stringInput' , 20)";
      
          new PythonFileReader(path, pyFileName, methodeName );
      }
      

      这是我的python类

      class test:
      
      def test(name, count):
          print(name + " - " + str([x for x in range(count)]))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多