最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java調用Python代碼的幾種方法小結

 更新時間:2025年01月09日 11:02:58   作者:夢想畫家  
Python語言有豐富的系統(tǒng)管理、數(shù)據(jù)處理、統(tǒng)計類軟件包,因此從java應用中調用Python代碼的需求很常見、實用,本文介紹幾種方法從java調用Python代碼,從而最大化利用兩個語言的優(yōu)勢,需要的朋友可以參考下

引言

Python語言有豐富的系統(tǒng)管理、數(shù)據(jù)處理、統(tǒng)計類軟件包,因此從java應用中調用Python代碼的需求很常見、實用。DataX 是阿里開源的一個異構數(shù)據(jù)源離線同步工具,致力于實現(xiàn)包括關系型數(shù)據(jù)庫(MySQL、Oracle等)、HDFS、Hive、ODPS、HBase、FTP等各種異構數(shù)據(jù)源之間穩(wěn)定高效的數(shù)據(jù)同步功能。Datax也是通過Java調用Python腳本。本文介紹幾種方法從java調用Python代碼,從而最大化利用兩個語言的優(yōu)勢。

Java core

Java提供了有兩種方法,分別為ProcessBuilder API和 JSR-223 Scripting Engine。

使用ProcessBuilder

通過ProcessBuilder創(chuàng)建本地操作系統(tǒng)進程啟動python并執(zhí)行Python腳本, hello.py腳本簡單輸出“Hello Python!”。需要開發(fā)環(huán)境已經安裝了python,并設置了環(huán)境變量。

@Test
public void givenPythonScript_whenPythonProcessInvoked_thenSuccess() throws Exception {
    ProcessBuilder processBuilder = new ProcessBuilder("python", resolvePythonScriptPath("hello.py"));
    processBuilder.redirectErrorStream(true);

    Process process = processBuilder.start();
    List<String> results = readProcessOutput(process.getInputStream());

    assertThat("Results should not be empty", results, is(not(empty())));
    assertThat("Results should contain output of script: ", results, hasItem(containsString("Hello Python!")));

    int exitCode = process.waitFor();
    assertEquals("No errors should be detected", 0, exitCode);
}

private List<String> readProcessOutput(InputStream inputStream) throws IOException {
    try (BufferedReader output = new BufferedReader(new InputStreamReader(inputStream))) {
        return output.lines()
            .collect(Collectors.toList());
    }
}

private String resolvePythonScriptPath(String filename) {
    File file = new File("src/test/resources/" + filename);
    return file.getAbsolutePath();
}

首先啟動帶一個參數(shù)的python命令,參數(shù)為python腳本的絕對路徑。可以放在java工程的resources目錄下。需要注意的是:redirectErrorStream(true),為了使得當執(zhí)行腳本出現(xiàn)錯誤時,錯誤輸出流被合并至標準輸出流。這樣設置可以從Process對象的getInputStream()方法中讀取錯誤信息。如果沒有該設置,則需要分別用兩個方法獲取流:getInputStream() 和 getErrorStream() 。processBuilder.start()獲取Process對象,然后讀取輸出流并驗證結果。

使用Java腳本引擎

java6首次引入JSR-223規(guī)范,定義一組提供基本腳本功能的腳本API。這些API提供了執(zhí)行腳本和在Java和腳本語言之間共享值的機制。該規(guī)范主要目的是為了統(tǒng)一Java與不同實現(xiàn)JVM的動態(tài)腳本語言的交互,Jython是在jvm上運行python的java實現(xiàn)。假設我們在CLASSPATH上有Jython,框架自動發(fā)現(xiàn)我們有可能使用該腳本引擎,并允許我們直接請求Python腳本引擎。因為Maven有Jython,我們可以在maven中引用,當然也下載直接安裝:

<dependency>
    <groupId>org.python</groupId>
    <artifactId>jython</artifactId>
    <version>2.7.2</version>
</dependency>

可以通過下面代碼列出所有支持的腳本引擎:

public static void listEngines() {
    ScriptEngineManager manager = new ScriptEngineManager();
    List<ScriptEngineFactory> engines = manager.getEngineFactories();

    for (ScriptEngineFactory engine : engines) {
        LOGGER.info("Engine name: {}", engine.getEngineName());
        LOGGER.info("Version: {}", engine.getEngineVersion());
        LOGGER.info("Language: {}", engine.getLanguageName());

        LOGGER.info("Short Names:");
        for (String names : engine.getNames()) {
            LOGGER.info(names);
        }
    }
}

如果Jython在環(huán)境中可用,應該看到相應的輸出:

...
Engine name: jython
Version: 2.7.2
Language: python
Short Names:
python
jython

現(xiàn)在使用Jython調用hello.py腳本:

@Test
public void givenPythonScriptEngineIsAvailable_whenScriptInvoked_thenOutputDisplayed() throws Exception {
    StringWriter writer = new StringWriter();
    ScriptContext context = new SimpleScriptContext();
    context.setWriter(writer);

    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByName("python");
    engine.eval(new FileReader(resolvePythonScriptPath("hello.py")), context);
    assertEquals("Should contain script output: ", "Hello Python!", writer.toString().trim());
}

使用該API比上面的示例更簡潔。首先設置ScriptContext包含StringWriter,用于保存執(zhí)行腳本的輸出。然后提供簡稱讓ScriptEngineManager 查找腳本引擎,可以使用python或jython。最后驗證輸出是否與期望一致。

其實也可以使用PythonInterpretor 類直接調用嵌入的python代碼:

@Test
public void givenPythonInterpreter_whenPrintExecuted_thenOutputDisplayed() {
    try (PythonInterpreter pyInterp = new PythonInterpreter()) {
        StringWriter output = new StringWriter();
        pyInterp.setOut(output);

        pyInterp.exec("print('Hello Python!')");
        assertEquals("Should contain script output: ", "Hello Python!", output.toString().trim());
    }
}

使用PythonInterpreter類,可以通過exec方法直接執(zhí)行python代碼。和前面示例一樣通過StringWriter 捕獲執(zhí)行輸出。下面再看一個示例:

@Test
public void givenPythonInterpreter_whenNumbersAdded_thenOutputDisplayed() {
    try (PythonInterpreter pyInterp = new PythonInterpreter()) {
        pyInterp.exec("x = 10+10");
        PyObject x = pyInterp.get("x");
        assertEquals("x: ", 20, x.asInt());
    }
}

上面示例可以使用get方法訪問變量值。下面示例看如何捕獲錯誤:

try (PythonInterpreter pyInterp = new PythonInterpreter()) {
    pyInterp.exec("import syds");
}

運行上面代碼會拋出PyException 異常,與在本地執(zhí)行Python腳本輸出錯誤一樣。
下面有幾點注意事項:

  • PythonIntepreter 實現(xiàn)了AutoCloseable,最好與 try-with-resources 一起使用。
  • PythonIntepreter類名不是表示Python代碼的解析器,Python程序在Jython是運行在jvm中,執(zhí)行前需要編譯為java字節(jié)碼。
  • 盡管Jython是Java的Python實現(xiàn),但它可能不包含與本機Python相同的所有子包。

下面示例展示如何把java變量賦給Python變量:

import org.python.util.PythonInterpreter; 
import org.python.core.*; 
 
class test3{
    public static void main(String a[]){

        int number1 = 10;
        int number2 = 32;
    
        try (PythonInterpreter pyInterp = new PythonInterpreter()) {
            python.set("number1", new PyInteger(number1));
            python.set("number2", new PyInteger(number2));

            python.exec("number3 = number1+number2");
            PyObject number3 = python.get("number3");

            System.out.println("val : "+number3.toString());
        }
    }
}

總結

本文介紹了如何從Java調用Python腳本,使用jython腳本引擎比ProcessBuilder類更簡單。另外Python可以便捷搭建http應用,Java也可以通過HTTP協(xié)議直接調用HTTP服務實現(xiàn)交互。

到此這篇關于Java調用Python代碼的幾種方法小結的文章就介紹到這了,更多相關Java調用Python代碼內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • eclipse實現(xiàn)ECDSA數(shù)字簽名

    eclipse實現(xiàn)ECDSA數(shù)字簽名

    這篇文章主要為大家詳細介紹了eclipse實現(xiàn)ECDSA數(shù)字簽名,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • 通過springboot發(fā)布WebService接口并調用方式

    通過springboot發(fā)布WebService接口并調用方式

    Spring Boot集成CXF需注意版本對應,配置注解并發(fā)布服務,通過WSDL驗證,結合Controller和Swagger測試,CXF支持SOAP、REST等服務,提供代碼與合同優(yōu)先開發(fā)模式
    2025-09-09
  • Spring配置多個數(shù)據(jù)源并實現(xiàn)動態(tài)切換示例

    Spring配置多個數(shù)據(jù)源并實現(xiàn)動態(tài)切換示例

    本篇文章主要介紹了Spring配置多個數(shù)據(jù)源并實現(xiàn)動態(tài)切換示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • 詳解@ConditionalOnMissingBean注解的作用

    詳解@ConditionalOnMissingBean注解的作用

    這篇文章主要介紹了詳解@ConditionalOnMissingBean注解的作用,@ConditionalOnMissingBean,它是修飾bean的一個注解,主要實現(xiàn)的是,當你的bean被注冊之后,如果而注冊相同類型的bean,就不會成功,它會保證你的bean只有一個,需要的朋友可以參考下
    2023-10-10
  • Mybatis一級緩存和結合Spring Framework后失效的源碼探究

    Mybatis一級緩存和結合Spring Framework后失效的源碼探究

    這篇文章主要介紹了Mybatis一級緩存和結合Spring Framework后失效的源碼探究,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • 在Spring boot的項目中使用Junit進行單體測試

    在Spring boot的項目中使用Junit進行單體測試

    今天小編就為大家分享一篇關于spring boot使用Junit進行測試,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • Spring Cloud  Eureka服務治理的實現(xiàn)

    Spring Cloud Eureka服務治理的實現(xiàn)

    服務治理是微服務框架中最為核心和基礎的模塊,它主要是用來實現(xiàn)各個微服務實例的自動化注冊與發(fā)現(xiàn)。這篇文章主要介紹了Spring Cloud Eureka服務治理的實現(xiàn),感興趣的小伙伴們可以參考一下
    2018-06-06
  • Spring?Boot?整合持久層之MyBatis

    Spring?Boot?整合持久層之MyBatis

    在實際開發(fā)中不僅僅是要展示數(shù)據(jù),還要構成數(shù)據(jù)模型添加數(shù)據(jù),這篇文章主要介紹了SpringBoot集成Mybatis操作數(shù)據(jù)庫,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • 使用Feign配置請求頭以及支持Https協(xié)議

    使用Feign配置請求頭以及支持Https協(xié)議

    這篇文章主要介紹了使用Feign配置請求頭以及支持Https協(xié)議,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • IDEA中在啟動 SpringBoot項目時加參數(shù)的方法步驟

    IDEA中在啟動 SpringBoot項目時加參數(shù)的方法步驟

    我們經常需要在啟動 Spring Boot 項目的時候,臨時修改一些參數(shù),例如 端口號、運行環(huán)境(profile)、日志級別 等等,除了在 application.yml 文件里修改,我們還可以通過在 IDEA 啟動配置中添加參數(shù)的方式來實現(xiàn),下面就來介紹一下
    2025-12-12

最新評論

互助| 灵山县| 兴安盟| 永州市| 边坝县| 来凤县| 吴旗县| 准格尔旗| 民乐县| 武鸣县| 丽江市| 兰州市| 拜城县| 怀集县| 江津市| 宁城县| 乌兰县| 宕昌县| 即墨市| 营口市| 广灵县| 南康市| 黑龙江省| 视频| 汶上县| 宁明县| 凌海市| 海安县| 南阳市| 胶南市| 安龙县| 汉沽区| 杭锦旗| 方山县| 长乐市| 永宁县| 明星| 云龙县| 土默特右旗| 洪雅县| 河西区|