Jython
1. 下載和安裝 Jython是一個Python的實現(xiàn),它允許我們在Java環(huán)境中運行Python代碼。首先,我們需要從官方網(wǎng)站(http://www.jython.org/)下載Jython的jar文件。然后,將其添加到Java項目的類路徑中。
2. 在Java代碼中使用Jython 要使用Jython,我們需要導(dǎo)入相應(yīng)的類并創(chuàng)建一個PythonInterpreter對象。以下是一個簡單的示例:
import org.python.util.PythonInterpreter;
import org.python.core.*;
public class JavaCallPython {
public static void main(String[] args) {
try (PythonInterpreter pyInterp = new PythonInterpreter()) {
pyInterp.exec("print('Hello, World!')"); // 執(zhí)行Python代碼
} catch (Exception e) {
e.printStackTrace();
}
}
}3. Python與Java之間的數(shù)據(jù)交互 要在Java中調(diào)用Python函數(shù)并傳遞參數(shù),我們可以使用PythonFunction對象。以下是一個示例:
import org.python.util.PythonInterpreter;
import org.python.core.*;
public class JavaCallPython {
public static void main(String[] args) {
try (PythonInterpreter pyInterp = new PythonInterpreter()) {
// 定義Python函數(shù)
PyObject pyFunc = pyInterp.eval("def add(a, b): return a + b");
PythonFunction javaFunc = new PythonFunction(pyFunc); // 將Python函數(shù)包裝成Java可調(diào)用的對象
int result = javaFunc.__call__(new PyInteger(3), new PyInteger(4)).asInt(); // 調(diào)用Python函數(shù)并傳遞參數(shù)
System.out.println("The result is: " + result); // 輸出結(jié)果
} catch (Exception e) {
e.printStackTrace();
}
}
}Java Runtime API
1. 加載Python解釋器類 要使用Java Runtime API調(diào)用Python腳本,我們需要先加載Python解釋器類,然后通過反射API調(diào)用其中的main方法。以下是一個示例:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import org.python.core.PyObject;
import org.python.util.PythonInterpreter;
import org.python.util.path.PathSourceLocator;
import org.python.util.path.PathSourceLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JavaCallPythonViaRuntimeAPI {
private static final Logger logger = LoggerFactory.getLogger(JavaCallPythonViaRuntimeAPI.class);
private static final String pythonScriptPath = "path/to/your/python/script"; // Python腳本的路徑
public static void main(String[] args) throws Exception {
// 1. 加載Python解釋器類并創(chuàng)建實例
URL url = new URL("file://" + pythonScriptPath); // 如果是本地文件,請使用"file://",如果是遠(yuǎn)程文件,請使用"hdfs://"等協(xié)議前綴加上URL地址
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{url}); // 如果需要加載多個文件,請將它們也加入到URL數(shù)組中,如:new URL[]{url1, url2, ...}
Class<?> pythonInterpreterClass = Class.forName("org.python.util.PythonInterpreter", true, urlClassLoader); // 注意:如果使用的是Windows系統(tǒng),請將反斜杠替換為雙反斜杠\\
PythonInterpreter pythonInterpreter = (PythonInterpreter) pythonInterpreterClass.getConstructor().newInstance(); // 注意:這里需要傳入一個Map<String, String>類型的參數(shù),用于設(shè)置環(huán)境變量等配置信息,但在這個示例中我們暫時不關(guān)心這些細(xì)節(jié),所以直接省略該構(gòu)造函數(shù)的調(diào)用
// 2. 執(zhí)行Python腳本
Object scriptModule = pythonInterpreterClass.getMethod("exec", String[].class).invoke(pythonInterpreter, new Object[]{pythonScriptPath}); // 注意:這里的"exec"方法實際上是執(zhí)行了一個包含main函數(shù)的模塊,而不是直接執(zhí)行了整個腳本
Method pythonMainMethod = scriptModule instanceof PyObject ? ((PyObject) scriptModule).getAttribute("__main__").getType().getMethod("main", String[].class) : null; // 注意:這個方法只能在實現(xiàn)了__main__屬性的模塊中使用
if (pythonMainMethod != null) { // 如果存在名為__main__的屬性,說明這是一個可以通過main函數(shù)入口執(zhí)行的模塊
String[] mainArgs = new String[] {"arg1", "arg2", "arg3"}; // 這里可以替換為你想要傳遞給Python腳本的參數(shù)
pythonMainMethod.__invoke__(mainArgs); // 注意:這里的"__invoke__"方法比前面提到的"exec"方法更底層一些
} else { // 如果不存在名為__main__的屬性,說明這是一個普通的純文本腳本
Method read = scriptModule instanceof PyObject && ((PyObject) scriptModule).getType().isSubtypeOf(PyUnicode.__TYPE__) ? ((PyObject) scriptModule).getType().getMethod("read", String[].class) : null; // 注意:這個方法只有在實現(xiàn)了Unicode字符集的模塊中才有效
if (read == null) throw new RuntimeException(\"Unable to execute the script: it may not support standard input or output\"); // 如果仍然無法執(zhí)行腳本,說明它并不支持標(biāo)準(zhǔn)輸入或輸出
BufferedReader bufferedReader = new BufferedReader((Reader) read.__invoke__(new Object[]{new String[0]})); // 注意:如果使用了非標(biāo)準(zhǔn)的輸入/輸出方式,需要根據(jù)實際情況修改這個構(gòu)造過程
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line); // 這里可以替換為你需要對每一行進行的處理邏輯
}
bufferedReader.close();
}
}
}