欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中調(diào)用Python的實(shí)現(xiàn)示例

 更新時(shí)間:2023年05月05日 08:52:39   作者:夢(mèng)想畫家  
本文主要介紹了Java中調(diào)用Python的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

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

Java core

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

使用ProcessBuilder

通過ProcessBuilder創(chuàng)建本地操作系統(tǒng)進(jìn)程啟動(dòng)python并執(zhí)行Python腳本, hello.py腳本簡(jiǎn)單輸出“Hello Python!”。需要開發(fā)環(huán)境已經(jīng)安裝了python,并設(shè)置了環(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();
}

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

使用Java腳本引擎

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

<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)境中可用,應(yīng)該看到相應(yīng)的輸出:

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

現(xiàn)在使用Jython調(diào)用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比上面的示例更簡(jiǎn)潔。首先設(shè)置ScriptContext包含StringWriter,用于保存執(zhí)行腳本的輸出。然后提供簡(jiǎn)稱讓ScriptEngineManager 查找腳本引擎,可以使用python或jython。最后驗(yàn)證輸出是否與期望一致。

其實(shí)也可以使用PythonInterpretor 類直接調(diào)用嵌入的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í)行輸出。下面再看一個(gè)示例:

@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方法訪問變量值。下面示例看如何捕獲錯(cuò)誤:

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

運(yùn)行上面代碼會(huì)拋出PyException 異常,與在本地執(zhí)行Python腳本輸出錯(cuò)誤一樣。

下面有幾點(diǎn)注意事項(xiàng):

  • PythonIntepreter 實(shí)現(xiàn)了AutoCloseable,最好與 try-with-resources 一起使用。
  • PythonIntepreter類名不是表示Python代碼的解析器,Python程序在Jython是運(yùn)行在jvm中,執(zhí)行前需要編譯為java字節(jié)碼。
  • 盡管Jython是Java的Python實(shí)現(xiàn),但它可能不包含與本機(jī)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());
? ? ? ? }
? ? }
}

總結(jié)

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

參考內(nèi)容:https://www.baeldung.com/java-working-with-python

到此這篇關(guān)于Java中調(diào)用Python的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Java調(diào)用Python內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決java調(diào)用python代碼返回值中文亂碼問題

    解決java調(diào)用python代碼返回值中文亂碼問題

    這篇文章主要介紹了解決java調(diào)用python代碼返回值中文亂碼問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Java多種經(jīng)典排序算法(含動(dòng)態(tài)圖)

    Java多種經(jīng)典排序算法(含動(dòng)態(tài)圖)

    排序算法是老生常談的了,但是在面試中也有會(huì)被問到,例如有時(shí)候,在考察算法能力的時(shí)候,不讓你寫算法,就讓你描述一下,某個(gè)排序算法的思想以及時(shí)間復(fù)雜度或空間復(fù)雜度。我就遇到過,直接問快排的,所以這次我就總結(jié)梳理一下經(jīng)典的十大排序算法以及它們的模板代碼
    2021-04-04
  • Java線上問題排查神器Arthas實(shí)戰(zhàn)原理解析

    Java線上問題排查神器Arthas實(shí)戰(zhàn)原理解析

    原先我們Java中我們常用分析問題一般是使用JDK自帶或第三方的分析工具如jstat、jmap、jstack、?jconsole、visualvm、Java?Mission?Control、MAT等,還有一款神器Arthas工具,可幫助程序員解決很多繁瑣的問題,感興趣的朋友一起看看吧
    2022-01-01
  • java字符串如何只保留數(shù)字、字母、中文

    java字符串如何只保留數(shù)字、字母、中文

    這篇文章主要介紹了java字符串如何只保留數(shù)字、字母、中文問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Java使用Tess4J實(shí)現(xiàn)圖像識(shí)別方式

    Java使用Tess4J實(shí)現(xiàn)圖像識(shí)別方式

    這篇文章主要介紹了Java使用Tess4J實(shí)現(xiàn)圖像識(shí)別方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java如何實(shí)現(xiàn)可折疊Panel方法示例

    Java如何實(shí)現(xiàn)可折疊Panel方法示例

    這篇文章主要給大家介紹了關(guān)于利用Java如何實(shí)現(xiàn)可折疊Panel的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07
  • Java工具類BeanUtils庫(kù)介紹及實(shí)例詳解

    Java工具類BeanUtils庫(kù)介紹及實(shí)例詳解

    這篇文章主要介紹了Java工具類BeanUtils庫(kù)介紹及實(shí)例詳解,需要的朋友可以參考下
    2020-02-02
  • Java 并發(fā)編程學(xué)習(xí)筆記之Synchronized簡(jiǎn)介

    Java 并發(fā)編程學(xué)習(xí)筆記之Synchronized簡(jiǎn)介

    雖然多線程編程極大地提高了效率,但是也會(huì)帶來一定的隱患。比如說兩個(gè)線程同時(shí)往一個(gè)數(shù)據(jù)庫(kù)表中插入不重復(fù)的數(shù)據(jù),就可能會(huì)導(dǎo)致數(shù)據(jù)庫(kù)中插入了相同的數(shù)據(jù)。今天我們就來一起討論下線程安全問題,以及Java中提供了什么機(jī)制來解決線程安全問題。
    2016-05-05
  • Spring的兩種事務(wù)管理機(jī)制的基本概念和demo示例

    Spring的兩種事務(wù)管理機(jī)制的基本概念和demo示例

    Spring事務(wù)包括聲明式事務(wù)管理和注解式事務(wù)管理,我們通過概念和小demo的形式一步一步地來一起學(xué)習(xí)這個(gè)知識(shí)點(diǎn),需要的朋友可以參考下
    2023-07-07
  • java定位死鎖的三種方法(jstack、Arthas和Jvisualvm)

    java定位死鎖的三種方法(jstack、Arthas和Jvisualvm)

    這篇文章主要給大家介紹了關(guān)于java定位死鎖的三種方法,分別是通過jstack定位死鎖信息、通過Arthas工具定位死鎖以及通過 Jvisualvm 定位死鎖,文中還介紹了死鎖的預(yù)防方法,需要的朋友可以參考下
    2021-09-09

最新評(píng)論