本文轉載自【微信公眾號:五角錢的程式設計師,ID:xianglin965】,經微信公眾號授權轉載,如需轉載與原文作者聯繫
圖丨pexels
java調用python的幾種用法(看這篇就夠了)
在java類中直接執行python語句
準備工作:
創建maven工程,結構如下:到官網
https://www.jython.org/download.html
下載Jython的jar包或者在maven的pom.xml文件中加入如下代碼:
<dependency>java<groupId>org.python</groupId> <artifactId>jython-standalone</artifactId> <version>2.7.0</version></dependency>
創建JavaRunPython.java類:
import org.python.util.PythonInterpreter;public class JavaRunPython {public static void main(String[] args) { PythonInterpreter interpreter = new PythonInterpreter(); interpreter.exec("a='hello world'; "); interpreter.exec("print a;"); }}
2.在java中直接調用python腳本
在本地的D盤創建一個python腳本,文件名字為javaPythonFile.py,文件內容如下:
a = 1b = 2print (a + b)
創建JavaPythonFile.java類,內容如下:
import org.python.util.PythonInterpreter;public class JavaPythonFile {public static void main(String[] args) { PythonInterpreter interpreter = new PythonInterpreter(); interpreter.execfile("D:\\javaPythonFile.py"); }}
輸出結果如下:
注意:以上兩個方法雖然都可以調用python程序,但是使用Jpython調用的python庫不是很多,如果你用以上兩個方法調用,而python的程序中使用到第三方庫,這時就會報錯java ImportError: No module named xxx。遇到這種情況推薦使用下面的方法,即可解決該問題。
3.使用Runtime.getRuntime()執行python腳本文件,推薦使用
為了驗證該方法可以運行含有python第三方庫的程序,在本地的D盤創建一個python腳本,文件名字為demo1.py,代碼如下:
import numpy as npa = 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 sysdef 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[] args1 = 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();}
在來一個實戰案例---模型獲取相似關鍵詞:
調用pyhon模型
java代碼
package com.hadoop.flowsum;/*
作者 :XiangLin創建時間 :2020/10/26 9:55文件 :testpython.javaIDE :IntelliJ IDEA*/import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Set;public class Demo1 {public static String getType(Object o){ //獲取變bai量類型方法du return o.getClass().toString(); //使用int類型的getClass()方法 } public static void main(String[] args) throws IOException, InterruptedException { // TODO Auto-generated method stub String cmds = String.format("python D:word2vec\\testsimilar.py %s","中國"); Process pcs = Runtime.getRuntime().exec(cmds); pcs.waitFor(); BufferedReader in = new BufferedReader(new InputStreamReader(pcs.getInputStream(),"GB2312")); Map<String, String> map = new HashMap<>(); String line = null;// System.out.println(in.readLine()); while ((line = in.readLine()) != null) { System.out.println(line); String[] s = line.split("\t");// System.out.println(s[0]+s[1]); map.put(s[0],s[1]); }// System.out.println(in.readLine()); if (in.readLine() == null){ System.out.println("yes hhhhhh"); }// String key1 = (String) map.keySet().toArray()[0]; String key1 = (String) map.keySet().toArray()[0]; String d1 = map.get(key1); double xx = Double.parseDouble(d1);// System.out.println(getType(xx));// if (xx > 0.6){// System.out.println("nice ................");// } }}
python代碼:
# * coding:utf-8_*_# 作者 :XiangLin# 創建時間 :2020/10/26 9:14# 文件 :testsimilar.py# IDE :PyCharmimport osimport timeimport warningsimport sys# import config# import loggingfrom gensim.models import Word2Vec# from gensim.models.word2vec import LineSentence, PathLineSentences# from pretreatment.pretreatment import PreDealwarnings.filterwarnings(action='ignore', category=UserWarning, module='gensim')model = Word2Vec.load(r"D:\\model\\word2vec.model")def similarwords(keyword, tops=5):# 默認獲取前10個相似關鍵詞 start = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) # print("start execute Word2vec, get similar keywords! Time:" + start +">>>>>>>>>>>>>>>>>>>>>") try: # model = Word2Vec.load(modelpath) words = model.wv.most_similar(keyword, topn=tops) except KeyError: # print("word '%s' not in vocabulary" % keyword) return None end = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) if not words: return None # res = [[item[0], item[1]] for item in words] # 相似關鍵詞及其相似度 res = [] for word in words: res.append([word[0], word[1]]) print(word[0], "\t", word[1]) # print("get similar keywords end!................... Time:" + end + ">>>>>>>>>>>>>>>>>>>>>") # print(res) return resif __name__ == '__main__': word = sys.argv[1]; similarwords(word)
輸出: