在java中调用python
1.Jython简介
原为JPython,可以理解为是一个用Java语言编写的Python解释器。使用Jython只需要在Java工程中引入Jython的jar包即可,使用Maven管理非常简单,只需添加相应的依赖即可。
1 <dependency> 2 <groupId>org.python</groupId> 3 <artifactId>jython-standalone</artifactId> 4 <version>2.7.0</version> //对应版本号,可以使用最新版的Jython,在Maven官网查找相应版本,会自动生成pom中依赖标签。 5 </dependency>
2.PythonInterpreter简介
PythonInterpreter的中文意思是“Python解释器”。在Java中我们可以直接实例化一个PythonInterpreter对象,使用它的exe方法可以直接在Java中执行Python语句输出结果。
1 import org.python.util.PythonInterpreter; //引入PythonInterpreter对象 2 public class HelloPython { 3 public static void main(String[] args) { 4 PythonInterpreter interpreter = new PythonInterpreter(); //实例化PythonInterpreter对象 5 interpreter.exec("print('hello')"); //利用PythonInterpreter的exec方法执行Python语句 6 } 7 }
3.如何在JVM中调用Pyhton编写的函数
如果需要在Java中直接调用Python脚本(.py文件),那我们还需另外两个对象的支持:PyFunction和PyObject。这两个对象在python的core包下。
1 import org.python.core.PyFunction; 2 import org.python.core.PyObject; 3 import org.python.util.PythonInterpreter; 4 5 public class HelloPython { 6 public static void main(String[] args) { 7 PythonInterpreter interpreter = new PythonInterpreter(); 8 interpreter.execfile("D:/labs/hello.py"); //使用PythonInterpreter的execfile方法获取相应目录下的Python脚本。这里的hello.py文件中包含一个函数:hello(),下一行代码中get方法中的第一个参数就是hello.py中的函数名或者变量名 9 10 PyFunction pyFunction = interpreter.get("hello", PyFunction.class); // 第一个参数为期望获得的函数(变量)的名字,第二个参数为期望返回的对象类型 11 PyObject pyObject = pyFunction.__call__(); // 调用函数 12 13 System.out.println(pyObject); 14 } 15 }
即使我们只调用Python脚本中的一个方法,我们也必须加载整个的.py文件,所以在边写脚本时,脚本也要实现模块化思想,避免加载不必要的方法,占用程序内存。
如果函数中需要参数,我们就需要在Java中将参数转化为对应的“Python类型”(也可以称为Jython类型),例如我们将Java中的int类型转变为Python中的int类型:new PyInteger(a)。类似的还有PyString、PyList等,可以通过查看相关API文档获取。
4.在本地环境中调用Python脚本
由于Jython运行过慢,且不支持第三方的Python模块,通过Java代码执行一段终端命令来调用Python脚本才是实际中真正会用到的方式。
1 import java.io.*; 2 3 class PyCaller { 4 private static final String DATA_SWAP = "temp.txt"; 5 private static final String PY_URL = System.getProperty("user.dir") + "\\test.py"; 6 7 public static void writeImagePath(String path) { 8 PrintWriter pw = null; 9 try { 10 pw = new PrintWriter(new FileWriter(new File(DATA_SWAP))); 11 } catch (IOException e) { 12 e.printStackTrace(); 13 } 14 pw.print(path); 15 pw.close(); 16 } 17 18 public static String readAnswer() { 19 BufferedReader br; 20 String answer = null; 21 try { 22 br = new BufferedReader(new FileReader(new File(DATA_SWAP))); 23 answer = br.readLine(); 24 } catch (FileNotFoundException e) { 25 e.printStackTrace(); 26 } catch (IOException e) { 27 e.printStackTrace(); 28 } 29 return answer; 30 } 31 32 public static void execPy() { 33 Process proc = null; 34 try { 35 proc = Runtime.getRuntime().exec("python " + PY_URL); 36 proc.waitFor(); 37 } catch (IOException e) { 38 e.printStackTrace(); 39 } catch (InterruptedException e) { 40 e.printStackTrace(); 41 } 42 } 43 44 // 测试码 45 public static void main(String[] args) throws IOException, InterruptedException { 46 writeImagePath("D:\\labs\\mytest\\test.jpg"); 47 execPy(); 48 System.out.println(readAnswer()); 49 } 50 }