[英]Java - How to call python classes using processbuilder
How do I call and execute python class methods from java.如何从 java 调用和执行 python 类方法。 My current java code works, but only if I write:
我当前的 java 代码有效,但前提是我写:
if __name__ == '__main__':
print("hello")
But I want to execute a class method, regardless of if __name__ == '__main__':
但是我想执行一个类方法,不管
if __name__ == '__main__':
Example python class method I would like to run:我想运行的示例python类方法:
class SECFileScraper:
def __init__(self):
self.counter = 5
def tester_func(self):
return "hello, this test works"
Essentially I would want to run SECFileScraper.tester_func() in java.基本上我想在 java 中运行 SECFileScraper.tester_func() 。
My Java code:我的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 is the file path to my python script. pdfFileScraper 是我的 python 脚本的文件路径。
I've tried jython, but my python files use pandas and sqlite3, which can't be implemented using jython.我试过jython,但是我的python文件使用了pandas和sqlite3,不能用jython实现。
So if I understand your requirement, you want to invoke a class method in pdfFileScraper.py
.因此,如果我理解您的要求,您想在
pdfFileScraper.py
调用一个类方法。 The basics of doing this from the shell would be something akin to:从 shell 执行此操作的基础类似于:
scraper=path/to/pdfFileScraper.py
dir_of_scraper=$(dirname $scraper)
export PYTHONPATH=$dir_of_scraper
python -c 'import pdfFileScraper; pdfFileScraper.ClassInScraper()'
What we do is get the directory of pdfFileScraper, and add it to the PYTHONPATH
, then we run python with a command that imports the pdfFileScraper file as a module, which exposes all the methods and classes in the class in the namespace pdfFileScraper
, and then construct a class ClassInScraper()
.我们所做的是获取 pdfFileScraper 的目录,并将其添加到
PYTHONPATH
,然后我们使用将 pdfFileScraper 文件作为模块导入的命令运行 python,它暴露了命名空间pdfFileScraper
中的类中的所有方法和类,然后构造一个ClassInScraper()
类。
In java, something like:在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);
}
}
}
You can also call Python lib directly via JNI.您也可以通过 JNI 直接调用 Python 库。 This way, you don't start new process, you can share context between script calls, etc.
这样,您就不会启动新进程,您可以在脚本调用之间共享上下文等。
Take a look here for a sample:在这里查看示例:
https://github.com/mkopsnc/keplerhacks/tree/master/python https://github.com/mkopsnc/keplerhacks/tree/master/python
This is my java class that worked for me.这是我的 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);
}}
and this is the way that you can use this class这就是你可以使用这个类的方式
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 );
}
and this is my python class这是我的python类
class test:
def test(name, count):
print(name + " - " + str([x for x in range(count)]))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.