java 调用python的相关问题说明与解决

本文重点介绍两种调用方式

前提,已搭建好正常的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 介绍完了。如若有不正确或描述不清楚的地方,欢迎评论指正。我会持续修正。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值