我在網上搜到的JAVA調用python程序的三種方式:
方式一:調用python函數。可以傳入參數,獲取返回值。
public static void PythonFunctionTest(){
//python 解釋器
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.execfile("E:\\Python_code\\helloPython.py");
PyFunction func=(PyFunction)interpreter.get("adder", PyFunction.class);
int a=2010;
int b=2;
PyObject pyobj = func.__call__(new PyInteger(a), new PyInteger(b));
System.out.println("answer= "+pyobj.toString());
}
方式二:直接執行python腳本。不能傳參,不能獲取返回值。 public static void PythonTextTest()
{
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.execfile("E:/Python_code/helloPython1.py");
}
方式三:在JAVA代碼裏面直接寫python程序,直接執行。這種方法顯然可以把參數傳進去,但是能不能獲得返回值需要進一步研究。
public static void PythonTest(){
PythonInterpreter interpreter =new PythonInterpreter();
interpreter.exec("days=('Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday')");
interpreter.exec("print days[0]");
}
考慮了一下,因爲第一種方式可以以調用函數的形式,同時即可以傳參又可以獲取返回值,所以我選擇了第一種方式用於在JAVA代碼塊中執行python程序。我在單獨的一個JAVA程序中執行相應代碼時,沒有問題,可以傳參也可以獲得返回的結果。但是當我把這段代碼放到現有的JAVAWEB的程序中時,會出現
java.lang.OutOfMemoryError:PermGen space內存溢出的問題。
於是我又按照網上的方法增到tomcat和eclipse的內存,結果無效。就這樣卡了很久後,我找到了第四種執行python程序的方法,這個方法不會產生內存溢出的問題。
方式四:使用控制檯執行python腳本,可以傳參和獲取返回值。
public static String runTimeMethod(String name,String path) {
try {
String cmd="python E:\\Python_code\\settingTest.py "+name+" "+path;
Process pr = Runtime.getRuntime().exec(cmd);
BufferedReader in = new BufferedReader(new InputStreamReader(
pr.getInputStream()));
String line="";
//輸出打印在控制檯上的結果
// while ((line = in.readLine()) != null) {
// System.out.println(line);
// }
//得到打印在控制檯上的結果
while ((line = in.readLine()) != null) {
result+=line;
}
in.close();
pr.waitFor();
// System.out.println("end");
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
其實這種方法就是在JAVA程序中執行控制檯命令,其效果等同於把python E:\\Python_code\\settingTest.py arg1 arg2
這段命令拷貝到cmd控制檯中。雖然可以傳入參數或獲取返回值,但其實它的實現並不是特別靈活和好用。下面是我用於測試的python代碼。
#coding=utf-8
import json
import sys
def JsonTestForDownloadApks(name,path):
print name,' ',path
name=sys.argv[1]
path=sys.argv[2]
JsonTestForDownloadApks(name,path)
可以看出,傳入參數的實現是通過python程序獲取控制檯輸入的方式。sys.arg[0]是當前python程序的執行路徑,sys.arg[1],sys.arg[2]是我們輸入的第一,二個參數。獲取返回結果是通過獲取打印到控制檯的輸出流獲的方式。其實這種方式有很大的侷限性,但是它起碼能迴避讓我頭疼的內存溢出問題,也能滿足我目前的功能需求,所以我選擇了這種方式。PS.因爲我對python的知識幾乎一無所知,對於python和JAVA之間的調用也是現學現用,所以我上面所說的方法可能非常低級甚至存在很大的風險,僅供大家參考。