如何使用Java调用Python程序java
本文为你们介绍如何java调用python方法,供你们参考。
实际工程项目中可能会用到Java和python两种语言结合进行,这样就会涉及到一个问题,就是怎么用Java程序来调用已经写好的python脚本呢,一共有三种方法能够实现,具体方法分别为你们介绍:python
1. 在java类中直接执行python语句程序员
此方法须要引用 org.python包,须要下载Jpython。在这里先介绍一下Jpython。下面引入百科的解释:app
这里我建议下载最新版本的Jpython,由于可使用的python函数库会比老版本的多些,目前最新版本为2.7。
下载jar包请点击Download Jython 2.7.0 - Standalone Jar
下载安装程序请点击Download Jython 2.7.0 - Installer
若是使用maven依赖添加的话,使用下面的语句maven
<dependency>
函数
<groupId>org.python</groupId>
测试
<artifactId>jython-standalone</artifactId>
url
<version>2.7.0</version>
spa
</dependency>
.net
以上准备好了,就能够直接在java类中写python语句了,具体代码以下:
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec("a=[5,2,3,9,4,0]; ");
interpreter.exec("print(sorted(a));"); //此处python语句是3.x版本的语法
interpreter.exec("print sorted(a);"); //此处是python语句是2.x版本的语法
输出结果以下:
这里会看到输出的结果都是同样的,也就是说Jpython兼容python2.x和3.x版本的语句,运行速度会比直接运行python程序稍慢一点。
可是每次运行结果都会提示console: Failed to install ”: java.nio.charset.UnsupportedCharsetException: cp0. 这样看起来很烦,由于每次运行结果都会出现红色的提示语句,觉得是错误,程序员应该都不肯意看到这一幕,得想个办法解决。
解决方法以下:
在要执行的代码上右键, Run As>Run Configurations,选择第二个页签Arguments,在VM arguments中添加如下语句
-Dpython.console.encoding=UTF-8
而后Apply->Run就能够了。
以下图所示:
2. 在java中调用本地python脚本
首先在本地创建一个python脚本,命名为add.py,写了一个简单的两个数作加法的函数,代码以下:
def add(a,b):
return a + b
python的功能函数已经写好,接下来咱们写一个java的测试类(一样须要用到Jpython包),来测试一下是否能够运行成功。代码以下:
import org.python.core.PyFunction;
import org.python.core.PyInteger;
import org.python.core.PyObject;
import org.python.util.PythonInterpreter;
public class Java_Python_test {
public static void main(String[] args) {
// TODO Auto-generated method stub
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.execfile("D:\\add.py");
// 第一个参数为指望得到的函数(变量)的名字,第二个参数为指望返回的对象类型
PyFunction pyFunction = interpreter.get("add", PyFunction.class);
int a = 5, b = 10;
//调用函数,若是函数须要参数,在Java中必须先将参数转化为对应的“Python类型”
PyObject pyobj = pyFunction.__call__(new PyInteger(a), new PyInteger(b));
System.out.println("the anwser is: " + pyobj);
}
}
运行结果如图所示:
OK,测试成功了~
关于Jpython更多详细的信息能够参考官方的相关文档,官网地址点这里。
注意:以上两个方法虽然均可以调用python程序,可是使用Jpython调用的python库不是不少,若是你用以上两个方法调用,而python的程序中使用到第三方库,这时就会报错java ImportError: No module named xxx。遇到这种状况推荐使用下面的方法,便可解决该问题。
为了验证该方法能够运行含有python第三方库的程序,咱们先写一个简单的python脚本,代码以下:
import numpy as np
a = np.arange(12).reshape(3,4)
print(a)
能够看到程序中用到了numpy第三方库,并初始化了一个3×4的一个矩阵。
下面来看看怎么用Runtime.getRuntime()方法来调用python程序并输出该结果,java代码以下:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Demo1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Process proc;
try {
proc = Runtime.getRuntime().exec("python D:\\demo1.py");// 执行py文件
//用输入输出流来截取结果
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
proc.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出的结果以下图所示:
能够看到运行成功了,但有的朋友可能会问了,怎么在python程序中函数传递参数并执行出结果,下面我就举一例来讲明一下。
先写一个python的程序,代码以下:
import sys
def func(a,b):
return (a+b)
if __name__ == '__main__':
a = []
for i in range(1, len(sys.argv)):
a.append((int(sys.argv[i])))
print(func(a[0],a[1]))
其中sys.argv用于获取参数url1,url2等。而sys.argv[0]表明python程序名,因此列表从1开始读取参数。
以上代码实现一个两个数作加法的程序,下面看看在java中怎么传递函数参数,代码以下:
int a = 18;
int b = 23;
try {
String[] args = new String[] { "python", "D:\\demo2.py", String.valueOf(a), String.valueOf(b) };
Process proc = Runtime.getRuntime().exec(args1);// 执行py文件
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
proc.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
其中args是String[] { “python”,path,url1,url2 }; ,path是python程序所在的路径,url1是参数1,url2是参数2,以此类推。
最后结果如图所示:
OK,成功了。
最后补充一点:
本人电脑上因为同时存在两个python,而我不想用默认的那个,也不想修改默认的python解释器,这种状况下,能够写一个bat文件,在bat文件中经过dos命令切换到该python所在目录,而后运行py文件(py文件要放在该目录下)
下面附上程序:
bat文件:
@echo off
C:
cd C:\Anaconda2\envs\py3
start python test.py
exit
java程序:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Demo1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Process proc;
try {
proc = Runtime.getRuntime().exec("cmd /c E:\\Faultdetection\\fault1\\run.bat");// 执行py文件
//用输入输出流来截取结果
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
proc.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}