如何使用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();
}
}
}