本文重点介绍两种调用方式
前提,已搭建好正常的python环境。
第一种通过Jython调用python ,先贴上代码吧
java代码:
public static void main(String args[]){
PySystemState sys = Py.getSystemState();
//加入python路径
sys.path.add("E:\\pathon_work");
sys.path.add("C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36-32");
sys.path.add("C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36-32\\DLLs");
sys.path.add("C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36-32\\lib");
sys.path.add("C:\\Users\\Administrator\\AppData\\Roaming\\Python\\Python36\\site-packages");
sys.path.add("C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\site-packages");
sys.path.add("C:\\Users\\Administrator\\AppData\\Roaming\\Python\\Python36\\site-packages\\numpy\\lib");
sys.path.add("C:\\Users\\Administrator\\AppData\\Roaming\\Python\\Python36\\site-packages\\numpy\\core");
//设置jython调用Python的属性
Properties props = new Properties();
props.put("python.home", "D:\\Program Files\\jython2.7.0\\Lib");
props.put("python.console.encoding", "UTF-8");
props.put("python.security.respectJavaAccessibility", "false");
props.put("python.import.site", "false");
Properties preprops = System.getProperties();
PythonInterpreter.initialize(preprops, props, new String[0]);
org.python.util.PythonInterpreter python = new org.python.util.PythonInterpreter();
StringWriter out = new StringWriter();
python.setOut(out);
python.execfile("E:/python_work/jython_java_test4.py");//执行python文件
PyFunction func = (PyFunction)python.get("adder",PyFunction.class); //获取python文件的函数
int a = 2010, b = 2 ; //初始化函数参数
PyObject pyobj = func.__call__(new PyInteger(a), new PyInteger(b));//调用python文件的函数,并传入参数,接收返回值
System.out.println("anwser = " + pyobj.toString());//打印出python的返回值
}
python--jython_java_test4.py代码
def addnum(arg1,arg2):
return arg1+arg2
如果jython环境没有问题的话,修改下调用python的文件路径,运行java的main函数就可以了。
jython环境配置参考如下:
安装jython参考连接:https://www.cnblogs.com/Sumomo0516/p/6025467.html
注意此种方式由于jython版本许入未更新,问题较多
如遇到console: Failed to install '': java.nio.charset.UnsupportedCharsetException: cp0.问题
做如下配置:运行配置-自变量-VM自变量加入
-Dpython.console.encoding=UTF-8
加入python路径到jython中
PySystemState sys = Py.getSystemState();
//加入python路径
sys.path.add("E:\\pathon_work");
sys.path.add("C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36-32");
sys.path.add("C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36-32\\DLLs");
sys.path.add("C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36-32\\lib");
sys.path.add("C:\\Users\\Administrator\\AppData\\Roaming\\Python\\Python36\\site-packages");
sys.path.add("C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\site-packages");
sys.path.add("C:\\Users\\Administrator\\AppData\\Roaming\\Python\\Python36\\site-packages\\numpy\\lib");
sys.path.add("C:\\Users\\Administrator\\AppData\\Roaming\\Python\\Python36\\site-packages\\numpy\\core");
添加jython-standalone-2.7.0.jar至java项目中,下载地址:http://www.jython.org/downloads.html(这里我用的是最新版本)
jython的简单示例就可以正常运行了。
效果如下:
如若python文件中有引入第三方库如numpy,sklearn,pandas等,那还是放弃这种方式吧!!!反正我是找了许久,没有找到合适的解决方法,若有大神解决了,可以回复我一下,让我也学习学习。
第二种方式,通过java调用进程的方式
基本思路为:通过java调用cmd,传入Python 命令,然后传入参数,通过获取到Python文件中的print,获取返回值
我使用的方式是,将数据存储到txt文件中,再将txt路径通过参数形式传入到Python,python调取文件,最后将返回结果print,java再获取print的数据。
本示例需要安装python 环境,安装numpy,matplotlib,sklearn等第三方库,这里就不详细描述了,网上资料很多。
java代码
public static void main(String args[]){
try{
System.out.println("start");
//python--python 运行的命令
//E:/python_work/jython_java_test4.py--python文件路径
//E:/python_work/testSet.txt--数据文件路径
String[] pythonData =new String[]{"python","E:/python_work/jython_java_test4.py","E:/python_work/testSet.txt"};
//读取到python文件
Process pr = Runtime.getRuntime().exec(pythonData);
InputStreamReader ir = new InputStreamReader(pr.getInputStream());
LineNumberReader in = new LineNumberReader(ir);
String line ;
//获取到python中的所有print 数据
while((line=in.readLine()) != null){
System.out.println("python print data"+line);
}
ir.close();
in.close();
pr.waitFor();
System.out.println("end");
}catch(Exception e){
e.printStackTrace();
}
}
python--jython_java_test4.py文件代码:
读者可屏蔽load_data方法,打开 数据样例--直接加载方式,直接运行python文件可看到效果
#coding=gbk
import numpy as np
from sklearn import svm
import matplotlib.pyplot as plt
import sys
X=[]
y=[]
#数据样例,java调用记取文件的方式
def load_data(filename):
with open(filename) as fileobj:
fileIn = fileobj.readlines()
for line in fileIn:
lineArr = line.strip().split('\t')
X.append([float(lineArr[0]),float(lineArr[1])])
y.append(float(lineArr[2]))
#load_data('E:/python_work/testSet.txt')
load_data(sys.argv[1]) #获取java传入的参数,即数据文件路径
#将数据转换为ndarray
X = np.array(X)
y = np.array(y)
"""
#数据样例--直接加载的方式
X = [[108,62],[112,75],[118,77],[122,75],[135,63],[117,78.5],[95,58.7],[100,68.5],[152,48.5],[162,50.1],[165,69],[190,58],[158,52],[185,82],[165,68],[174,64],[157,56],[170,62],[160,49],[178,72],[163,55],[173,63],[156,42],[188,91],[161,54],[181,75],[159,42],[177,76],[165,53],[185,46],[170,68]]
X = np.array(X)
y = [-1,-1,-1,-1,-1,-1,-1,-1,1,1,0,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1]
y = np.array(y)
"""
#预测样例
p = [[112,68],[165,48]]
p = np.array(p)
C=1.0
clf = svm.SVC(kernel='linear',decision_function_shape='ovo',C=C)
clf.fit(X,y)
ax = plt.gca()
XX ,YY= X[:,0],X[:,1]
x_min,x_max = XX.min()-1,XX.max()+1
y_min,y_max = YY.min()-1,YY.max()+1
xx,yy = np.meshgrid(np.arange(x_min,x_max,0.2),
np.arange(y_min,y_max,0.2))
Z = clf.predict(np.c_[xx.ravel(),yy.ravel()])
Z = Z.reshape(xx.shape)
ax.contourf(xx,yy,Z,cmap=plt.cm.coolwarm,edgecolors='k')
#根据不同的标签绘制不同的图标
index =0
for axs in X:
if y[index] == -1:
plt.scatter(axs[0],axs[1],c='c',s=30,edgecolor='none',marker='x')
elif y[index] == 0:
plt.scatter(axs[0],axs[1],c='r',s=30,edgecolor='none',marker='o')
elif y[index] == 1:
plt.scatter(axs[0],axs[1],c='y',s=30,edgecolor='none',marker='s')
index +=1
plt.xlim(xx.min(),xx.max())
plt.ylim(yy.min(),yy.max())
plt.xlabel('height')
plt.ylabel('weight')
x_ticks = np.linspace(xx.min(),xx.max(),10)
y_ticks = np.linspace(yy.min(),yy.max(),10)
plt.xticks(x_ticks)
plt.yticks(y_ticks)
plt.title('predict girl,boy and child')
#预测数据绘制
p_clf = clf.predict(p)
index =0
for axs in p:
if p_clf[index] == -1:
plt.scatter(axs[0],axs[1],c='b',s=30,edgecolor='none',marker='x')
elif p_clf[index] == 0:
plt.scatter(axs[0],axs[1],c='b',s=30,edgecolor='none',marker='o')
elif p_clf[index] == 1:
plt.scatter(axs[0],axs[1],c='b',s=30,edgecolor='none',marker='s')
index +=1
print('aaa')
print(p_clf)
plt.show()
数据文件中数据
108 62 -1
112 75 -1
118 77 -1
122 75 -1
135 63 -1
117 78.5 -1
95 58.7 -1
100 68.5 -1
152 48.5 1
162 50.1 1
165 69 0
190 58 0
158 52 1
185 82 0
165 68 0
174 64 0
157 56 1
170 62 0
160 49 1
178 72 0
163 55 1
173 63 0
156 42 1
188 91 0
161 54 1
181 75 0
159 42 1
177 76 0
165 53 1
185 46 0
170 68 1
运行效果如下
1.python文件的运行效果
java控制台效果:
java控制台的python print data数据就是 "aaa","[-1.,1.]"就是从python中print获取而来的。
到此java 调用python 介绍完了。如若有不正确或描述不清楚的地方,欢迎评论指正。我会持续修正。