iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java中调用Python的实现示例
  • 131
分享到

Java中调用Python的实现示例

java调用python脚本java调用python 2023-05-18 20:05:21 131人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录Java core使用ProcessBuilder使用Java脚本引擎总结python语言有丰富的系统管理、数据处理、统计类软件包,因此从java应用中调用Python代码的需求

python语言有丰富的系统管理、数据处理、统计类软件包,因此从java应用中调用Python代码的需求很常见、实用。DataX 是阿里开源的一个异构数据源离线同步工具,致力于实现包括关系型数据库(Mysqloracle等)、hdfsHive、ODPS、HBase、FTP等各种异构数据源之间稳定高效的数据同步功能。Datax也是通过Java调用Python脚本。本文介绍几种方法从java调用Python代码,从而最大化利用两个语言的优势。

Java core

Java提供了有两种方法,分别为ProcessBuilder apijsR-223 Scripting Engine。

使用ProcessBuilder

通过ProcessBuilder创建本地操作系统进程启动python并执行Python脚本, hello.py脚本简单输出“Hello Python!”。需要开发环境已经安装了python,并设置了环境变量。

@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();
}

首先启动带一个参数的python命令,参数为python脚本的绝对路径。可以放在java工程的resources目录下。需要注意的是:redirectErrorStream(true),为了使得当执行脚本出现错误时,错误输出流被合并至标准输出流。这样设置可以从Process对象的getInputStream()方法中读取错误信息。如果没有该设置,则需要分别用两个方法获取流:getInputStream() 和 getErrorStream() 。processBuilder.start()获取Process对象,然后读取输出流并验证结果。

使用Java脚本引擎

java6首次引入JSR-223规范,定义一组提供基本脚本功能的脚本API。这些API提供了执行脚本和在Java和脚本语言之间共享值的机制。该规范主要目的是为了统一Java与不同实现JVM的动态脚本语言的交互,Jython是在jvm上运行python的java实现。假设我们在CLASSPATH上有Jython,框架自动发现我们有可能使用该脚本引擎,并允许我们直接请求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在环境中可用,应该看到相应的输出:

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

现在使用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,用于保存执行脚本的输出。然后提供简称让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方法直接执行python代码。和前面示例一样通过StringWriter 捕获执行输出。下面再看一个示例:

@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 异常,与在本地执行Python脚本输出错误一样。

下面有几点注意事项:

  • PythonIntepreter 实现了AutoCloseable,最好与 try-with-resources 一起使用。
  • PythonIntepreter类名不是表示Python代码的解析器,Python程序在Jython是运行在jvm中,执行前需要编译为java字节码。
  • 尽管Jython是Java的Python实现,但它可能不包含与本机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协议直接调用HTTP服务实现交互。

参考内容:https://www.baeldung.com/java-working-with-python

到此这篇关于Java中调用Python的实现示例的文章就介绍到这了,更多相关Java调用Python内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java中调用Python的实现示例

本文链接: https://www.lsjlt.com/news/212390.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java中调用Python的实现示例
    目录Java core使用ProcessBuilder使用Java脚本引擎总结Python语言有丰富的系统管理、数据处理、统计类软件包,因此从java应用中调用Python代码的需求...
    99+
    2023-05-18
    java调用python脚本 java调用python
  • Java实现调用ElasticSearch API的示例详解
    目录java操作es有两种方式Elasticsearch-Rest-Client(官方,推荐)maven配置文件es配置类导包Spring Data ElasticSearch配置文...
    99+
    2023-03-02
    Java调用ElasticSearch API Java ElasticSearch API Java ElasticSearch
  • Java实现调用外部程序的示例代码
    目录Runtime类与ProcessBuilder类参数传递执行结果Runtime类的使用ProcessBuilder类的使用无参数调用简单参数调用复杂参数调用Apache Comm...
    99+
    2023-05-18
    Java 调用外部程序 java调用程序
  • Java实现作业调度的示例代码
    目录Java实现作业调度要求参考代码运行效果Java实现作业调度 要求 Java实现SJF算法调度,要求测试数据可以随即输入或从文件中读入; 必须要考虑到作业的到达时间; 最终能够计...
    99+
    2023-05-14
    Java实现作业调度 Java作业调度 Java调度
  • python中实现链式调用的案例
    小编给大家分享一下python中实现链式调用的案例,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!我们在使用Django的models查询数据库时,可以看到有这种写...
    99+
    2023-06-14
  • Python调用pytdx的代码示例
    目录安装pytdx简单示范一、基本行情接口索引二、扩展行情接口API安装pytdx pip install pytdx 简单示范 from pytdx.hq import TdxH...
    99+
    2023-01-28
    Python调用pytdx Python pytdx
  • 怎么用Java实现回调例程
    小编给大家分享一下怎么用Java实现回调例程,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!熟悉 MS-windows 和 X Window System 事件驱动...
    99+
    2023-06-03
  • Python中seaborn调色盘的示例分析
    这篇文章主要为大家展示了“Python中seaborn调色盘的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Python中seaborn调色盘的示例分析”这篇文章吧。1、color_pa...
    99+
    2023-06-29
  • Python中特殊传参的实现示例
    这篇文章主要介绍Python中特殊传参的实现示例,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1、说明/ 和 * 是可选的。这些符号表明形参如何把参数值传递给函数:位置、位置或关键字、关键字。/ 前面只能传递位置参数...
    99+
    2023-06-15
  • Java利用JavaCPP调用算法示例
    目录配置liunx 环境系统配置java 项目配置liunx 环境系统 配置so 文件存放路径 [root@arch2 ~]# cat /etc/ld.so.conf.d/so...
    99+
    2024-04-02
  • Java中使用同步回调和异步回调的示例详解
    目录(一)同步回调(1)匿名内部类回调(2)Lambda 回调(二)异步回调(1)简单的线程回调(2)异步并行回调(3)CompletableFuture 回调小结完整代码(一)同步...
    99+
    2023-05-16
    java同步回调 java异步回调 java异步和同步回调
  • Java实现中国象棋的示例代码
    目录前言主要设计功能截图代码实现总结前言 中国象棋是起源于中国的一种棋,属于二人对抗性游戏的一种,在中国有着悠久的历史。由于用具简单,趣味性强,成为流行极为广泛的棋艺活动。 中国象棋...
    99+
    2024-04-02
  • C#实现接口base调用示例详解
    目录背景方法1:使用反射找到接口实现并进行调用方法2:利用函数指针方法3:利用Fody在编译时对接口方法进行IL的call调用性能测试总结背景 在三年前发布的C#8.0中有一项重要的...
    99+
    2024-04-02
  • C#调用FFmpeg操作音视频的实现示例
    目录项目背景FFmpeg介绍FFmpeg相关教程博客示例源码下载FFmpeg.exe安装包C#进程调用FFmpeg操作音视频项目背景   因为公司需要对音视频做一些操作,比如说对系统...
    99+
    2024-04-02
  • C++实现与Lua相互调用的示例详解
    目录概述示例C++调用lua编译lua流程运行lua调用C++解释运行调用语义概述 从本质上来看,其实说是不存在所谓的C++与lua的相互调用。lua是运行在C上的,简单来说lua的...
    99+
    2023-05-13
    C++ Lua相互调用 C++ Lua 调用 C++ Lua
  • python调用系统中应用程序的函数示例
    目录os.system()os.popen()commands.getstatusoutput()subprocess.call()os.system() 在shell中执行一条命令...
    99+
    2024-04-02
  • java中class实例的示例分析
    这篇文章将为大家详细讲解有关java中class实例的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1、结构说明(1)class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类(2...
    99+
    2023-06-15
  • java实现Floyd算法的示例
    这篇文章给大家分享的是有关java实现Floyd算法的示例的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Floyd算法:用于多源最短路径的求解,算出来的是所有的节点到其余各节点之间的最短距离。该算法的思路是:首先...
    99+
    2023-05-30
  • Java实现FutureTask的示例详解
    目录前言FutureTask自己实现FutureTask工具准备FutureTask设计与实现总结前言 在并发编程当中我们最常见的需求就是启动一个线程执行一个函数去完成我们的需求,而...
    99+
    2022-11-13
    Java 实现FutureTask Java FutureTask
  • Java Swing中JDialog实现用户登陆UI示例
    本文实例讲述了Java Swing中JDialog实现用户登陆UI。分享给大家供大家参考,具体如下:JDialog是一种对话框组件,它常常与JOptionPane配合使用。JOptionPane提供对话框内部的消息、按钮等内容,JDialo...
    99+
    2023-05-30
    java swing jdialog
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作