在Java項目中調(diào)用Python代碼有多種方法,包括使用Jython、ProcessBuilder、Java Scripting API和JNI。每種方法都有其適用場景和優(yōu)缺點。小編將詳細介紹這些方法,并提供示例代碼。
1. 使用Jython
Jython是一個由Java編寫的Python解釋器,允許在Java環(huán)境中運行Python代碼。Jython作為Python在Java中的完整實現(xiàn),提供了對Python庫和Java類的訪問,具有豐富的資源庫。
步驟:
添加依賴:在Maven項目中添加Jython依賴。
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.7.0</version>
</dependency>
執(zhí)行Python代碼:使用PythonInterpreter類執(zhí)行Python代碼。
import org.python.util.PythonInterpreter;
import org.python.core.*;
public class InvokePython {
public static void main(String[] args) {
PythonInterpreter pythonInterpreter = new PythonInterpreter();
pythonInterpreter.exec("a='aaa'");
pythonInterpreter.exec("print(a)");
}
}
運行
調(diào)用Python函數(shù):加載Python腳本文件并調(diào)用其中的函數(shù)。
import org.python.util.PythonInterpreter;
import org.python.core.*;
public class CallPythonFunction {
public static void main(String[] args) {
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.execfile("D:/Workspaces/J2EE/Test/config/my_utils.py");
PyFunction func = (PyFunction) interpreter.get("adder", PyFunction.class);
int a = 2010, b = 6;
PyObject pyobj = func._call_(new PyInteger(a), new PyInteger(b));
System.out.println("answer = " + pyobj.toString());
}
}
運行
注意事項:
Jython支持的Python版本為2.7,不支持Python 3.x。
Jython不再積極開發(fā),可能不支持最新的Python庫。
2. 使用ProcessBuilder
ProcessBuilder用于啟動和管理操作系統(tǒng)進程,可以從Java中運行外部Python腳本并捕獲輸出。
步驟:
編寫Python腳本:創(chuàng)建一個Python腳本文件input.py 。
# open files
print('hello')
number = [3, 5, 2, 0, 6]
print(number)
number.sort()
print(number)
number.append(0)
print(number)
print(number.count(0))
print(number.index(5))
運行
使用ProcessBuilder調(diào)用Python腳本:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class TestPython {
public static void main(String[] args) throws Exception {
ProcessBuilder pb = new ProcessBuilder("python", "D:/Workspaces/J2EE/Test/config/input.py");
Process process = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("Exited with error code : " + exitCode);
}
}
運行
優(yōu)點:
可以使用Python的所有庫和模塊。
支持最新版本的Python。
缺點:
代碼相對復(fù)雜,可讀性較差。
需要處理進程的輸入輸出流。
3. 使用Java Scripting API
Java Scripting API(JSR 223)允許Java通過統(tǒng)一接口調(diào)用各種腳本語言,包括Python。
步驟:
添加依賴:確保項目中包含javax.script包。
使用ScriptEngineManager和ScriptEngine執(zhí)行Python代碼:import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class ScriptEngineExample {
public static void main(String[] args) {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("python");
try {
engine.eval("print('Hello from Python!')");
} catch (ScriptException e) {
e.printStackTrace();
}
}
}
運行
優(yōu)點:
提供統(tǒng)一接口調(diào)用多種腳本語言。
簡化了腳本語言的集成。
缺點:
需要額外的配置和依賴。
性能可能不如直接使用Jython或ProcessBuilder。
4. 使用JNI(Java Native Interface)
JNI使Java代碼能與C/C++編寫的代碼交互,從而間接調(diào)用Python代碼。
步驟:
編寫C/C++代碼:創(chuàng)建一個C/C++函數(shù)調(diào)用Python代碼。
使用JNI調(diào)用C/C++函數(shù):public class JNITest {
static {
System.loadLibrary("mylib");
}
private native void callPython();
public static void main(String[] args) {
new JNITest().callPython();
}
}
運行
優(yōu)點:
可以與C/C++代碼交互。
支持復(fù)雜的系統(tǒng)級操作。
缺點:
需要編寫和編譯C/C++代碼。
增加了項目的復(fù)雜性。
在選擇如何在Java中調(diào)用Python代碼時,應(yīng)根據(jù)具體需求和項目特點進行權(quán)衡。Jython適合頻繁調(diào)用Python代碼的場景,ProcessBuilder適用于簡單腳本調(diào)用,Java Scripting API提供統(tǒng)一接口調(diào)用腳本語言,JNI適用于與C/C++代碼交互。根據(jù)實際需求選擇合適的方法,可以有效提升開發(fā)效率和代碼的可維護性。