Java调用Python程序方法总结(最全最详细)-程序员宅基地

技术标签: 爬虫  python  java  

如何使用Java调用Python程序

本文为大家介绍如何java调用python方法,供大家参考。
实际工程项目中可能会用到Java和python两种语言结合进行,这样就会涉及到一个问题,就是怎么用Java程序来调用已经写好的python脚本呢,一共有三种方法可以实现,具体方法分别为大家介绍:

1.在Java类中直接执行python语句

此方法需要引用 org.python包,需要下载Jpython。在这里先介绍一下Jpython。下面引入百科的解释:

Jython是一种完整的语言,而不是一个Java翻译器或仅仅是一个Python编译器,它是一个Python语言在Java中的完全实现。Jython也有很多从CPython中继承的模块库。最有趣的事情是Jython不像CPython或其他任何高级语言,它提供了对其实现语言的一切存取。所以Jython不仅给你提供了Python的库,同时也提供了所有的Java类。这使其有一个巨大的资源库。

这里我建议下载最新版本的Jpython,因为可以使用的python函数库会比老版本的多些,目前最新版本为2.7。
下载jar包请点击Download Jython 2.7.0 - Standalone Jar
下载安装程序请点击Download Jython 2.7.0 - Installer
如果使用maven依赖添加的话,使用下面的语句

<dependency>
    <groupId>org.python</groupId>
    <artifactId>jython-standalone</artifactId>
    <version>2.7.0</version>
</dependency>

以上准备好了,就可以直接在java类中写python语句了,具体代码如下:

import org.python.util.PythonInterpreter;

public class Main {
    
    public static void main(String[] args) {
    
        PythonInterpreter interpreter = new PythonInterpreter();
        interpreter.exec("a=[5,4,3,2,1]");
        interpreter.exec("print(sorted(a))");
    }
}

在这里插入图片描述

2.在Java中调用本地python脚本

首先在本地建立一个python脚本,命名为add.py,写了一个简单的两个数做加法的函数,代码如下:

def add(a, b):
    return a + b

python的功能函数已经写好,接下来我们写一个java的测试类(同样需要用到Jpython包),来测试一下是否可以运行成功。代码如下:

import org.python.core.PyFunction;
import org.python.core.PyInteger;
import org.python.core.PyObject;
import org.python.util.PythonInterpreter;
 
public class Java_Python_test {
    
 
    public static void main(String[] args) {
    
        // TODO Auto-generated method stub
        PythonInterpreter interpreter = new PythonInterpreter();
        interpreter.execfile("D:\\add.py");
 
        // 第一个参数为期望获得的函数(变量)的名字,第二个参数为期望返回的对象类型
        PyFunction pyFunction = interpreter.get("add", PyFunction.class);
        int a = 5, b = 10;
        //调用函数,如果函数需要参数,在Java中必须先将参数转化为对应的“Python类型”
        PyObject pyobj = pyFunction.__call__(new PyInteger(a), new PyInteger(b)); 
        System.out.println("the anwser is: " + pyobj);
    }
}

在这里插入图片描述
注意:
以上两个方法虽然都可以调用python程序,但是使用Jpython调用的python库不是很多,如果你用以上两个方法调用,而python的程序中使用到第三方库,这时就会报错java ImportError: No module named xxx。遇到这种情况推荐使用下面的方法,即可解决该问题。

在这里插入图片描述

3.使用Runtime.getRuntime()执行脚本文件(推荐)

为了验证该方法可以运行含有python第三方库的程序,我们先写一个简单的python脚本,代码如下:

import numpy as np
 
a = np.arange(12).reshape(3,4)
print(a)

可以看到程序中用到了numpy第三方库,并初始化了一个3×4的一个矩阵。
下面来看看怎么用Runtime.getRuntime()方法来调用python程序并输出该结果,java代码如下:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Demo1 {
    
    public static void main(String[] args) {
    
        Process proc;
        try {
    
            proc = Runtime.getRuntime().exec("python D:\\IDEA\\spring4all\\JPython\\src\\main\\java\\demo1.py");//执行Py文件
            //用输入输出流来截取结果
            BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            String line = null;
            while ((line = in.readLine()) != null) {
    
                System.out.println(line);
            }
            in.close();
            proc.waitFor();
        } catch (IOException e) {
    
            e.printStackTrace();
        } catch (InterruptedException e) {
    
            e.printStackTrace();
        }
    }
}

在这里插入图片描述
可以看到运行成功了,但有的朋友可能会问了,怎么在python程序中函数传递参数并执行出结果,下面我就举一例来说明一下。
先写一个python的程序,代码如下:

import sys
 
def func(a,b):
    return (a+b)
 
if __name__ == '__main__':
    a = []
    for i in range(1, len(sys.argv)):
        a.append((int(sys.argv[i])))
 
    print(func(a[0],a[1]))

其中sys.argv用于获取参数url1,url2等。而sys.argv[0]代表python程序名,所以列表从1开始读取参数。
以上代码实现一个两个数做加法的程序,下面看看在java中怎么传递函数参数,代码如下:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Demo2 {
    
    public static void main(String[] args) {
    
        int a = 18, b = 23;
        try {
    
            String[] args1 = new String[]{
    "python", "D:\\IDEA\\spring4all\\JPython\\src\\main\\java\\demo2.py", String.valueOf(a), String.valueOf(b)};
            Process proc = Runtime.getRuntime().exec(args1);//执行PY文件
            BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            String line = null;
            while ((line=in.readLine())!=null){
    
                System.out.println(line);
            }
            in.close();
            proc.waitFor();
        } catch (IOException | InterruptedException e) {
    
            e.printStackTrace();
        }
    }
}

其中args是String[] { “python”,path,url1,url2 }; ,path是python程序所在的路径,url1是参数1,url2是参数2,以此类推。
最后结果如图所示:
在这里插入图片描述
最后补充一点:
本人电脑上由于同时存在两个python,而我不想用默认的那个,也不想修改默认的python解释器,这种情况下,可以写一个bat文件,在bat文件中通过dos命令切换到该python所在目录,然后运行py文件

py文件:

import time

print('hello!')
time.sleep(120)
print('bye!')

bat文件:

@echo off
D:
cd D:\ProgramData\Anaconda3
start python D:\IDEA\spring4all\JPython\src\main\java\test.py
exit

Java程序:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Demo3 {
    
    public static void main(String[] args) {
    
        Process proc;
        try {
    
            proc = Runtime.getRuntime().exec("cmd /c D:\\IDEA\\spring4all\\JPython\\src\\main\\java\\run.bat");
            //用输入输出流来截取结果
            BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            String line = null;
            while ((line=in.readLine())!=null){
    
                System.out.println(line);
            }
            in.close();
            proc.waitFor();
        } catch (IOException | InterruptedException e) {
    
            e.printStackTrace();
        }
    }
}

参考资料

  1. http://blog.csdn.net/it_xiao_bai/article/details/79074988
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_40507857/article/details/120041897

智能推荐

ORA-00132syntax error or unresolved network name-程序员宅基地

文章浏览阅读2.3k次。在DOS下SQL&gt; startup;ORA-00119: invalid specification for system parameter LOCAL_LISTENERORA-00132: syntax error or unresolved network name 'LISTENER_ORCL'解决方法:1.SQL&gt; create pfile from spf..._ora-00132

C/C++编程笔记:quick_exit函数和ctime函数-程序员宅基地

文章浏览阅读650次。今天给大家分享学习两个函数:quick_exit函数和ctime函数。quick_exitquick_exit()函数是在定义STDLIB头文件。quick_exit()函数用于正常终止进程而不完全清除资源。如果val为零或EXIT_SUCCESS,则表明程序成功终止。如果该值不为零或EXIT_FAILURE,则表明该程序未成功终止。这些函数以那里调用的相反顺序被调用。句法:void quick_exit(int val);参数:此方法采用单个参数val,它是表示程序退出状态_quick_exit

Oracle感慨(转)-程序员宅基地

文章浏览阅读60次。 一转眼接触ORACLE已经一年了,在这一年中收获多多,感慨多多,我记得是2004年11月底开始学习ORACLE的,当时选择方向也是几经波折,还好现在的处境不是非常的艰难,前途似乎还有想象中的光明。 毕业已经两年半,开始半年主要是接触Sybase,当时公司后台使用的Sybase SQL 11,由于人手比较少,管理也不很严格,所以我经常有机会光顾他,在那里我学会了怎样备份,恢复数..._李小龙语录一拳就是一拳一脚就是一脚

android关于自定义Dialog中布局match_parent 属性 失效的问题_android dialog 布局 match_parent 无效-程序员宅基地

文章浏览阅读1.9k次。dialog如果没有设置style,那么系统会主动设置一个style,这个style中的decorview会存在padding,所以导致match_parent无效1.方法一dialog.show();//在show之后修改,必须这样否则无效,没看源码具体原因不知道Window window =dialog.getWindow();if (window == null) {..._android dialog 布局 match_parent 无效

vue3+vite+ts的项目打包后使用静态资源dist用5+app打包成APP_vite vue ts 转 app-程序员宅基地

文章浏览阅读256次,点赞10次,收藏2次。使用app在真机上安装完成后,进入首页后登录时遇到了连不上后端api的问题,在处理完跨域的问题后,发现因为发布app时 vue开发模式下配置的跨域是无效的,打包后会找不到接口。使用HBuildeX创建5+app项目,然后删除。并将vue3打包出来的dist文件夹中的。全部内容复制到5+app项目中;_vite vue ts 转 app

毕设开源 基于Python的南京二手房数据采集及可视化分析-程序员宅基地

文章浏览阅读734次,点赞6次,收藏10次。首先通过爬虫采集链家网上所有南京二手房的房源数据,并对采集到的数据进行清洗;然后,对清洗后的数据进行可视化分析,探索隐藏在大量数据背后的规律;最后,采用一个聚类算法对所有二手房数据进行聚类分析,并根据聚类分析的结果,将这些房源大致分类,以对所有数据的概括总结。通过上述分析,我们可以了解到目前市面上二手房各项基本特征及房源分布情况,帮助我们进行购房决策。Python网络爬虫技术RequestsPython数据分析技术NumpyMatplotlibPandask-means聚类算法。

随便推点

学习cassandra(1)入门,使用场景(写多读少)和搭建启动使用,整合Spring boot_cassandra入门实战黑马程序员-程序员宅基地

文章浏览阅读2.3k次。官网http://cassandra.apache.org/ 下载后wget http://mirror.bit.edu.cn/apache/cassandra/3.11.1/apache-cassandra-3.11.1-bin.tar.gz解压tar -xvf apache-cassandra-3.11.1-bin.tar.gzcd apache-cassandra-3.11.1修改配置文件_cassandra入门实战黑马程序员

ES源码之路(一):源码本地编译启动_gradle编译es源码-程序员宅基地

文章浏览阅读1.7k次。ES源码之路(一):源码本地编译启动先来一段客套话,介绍一下ES:ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。ElasticSearch用于云计算中,能够达到实时搜索,稳定,可..._gradle编译es源码

React脚手架介绍和Demo_脚手架demo是什么-程序员宅基地

文章浏览阅读256次。React脚手架生成代码和Demo_脚手架demo是什么

插画人物怎么画?人体动态结构怎么画?_人体体块怎么画-程序员宅基地

文章浏览阅读3.2k次。动漫人物怎么画?人体动作怎么画?有多少绘画新手都是喜欢收藏大量人体图文或是人体视频教程,但是从来都从来都没有认真的练习过的,收藏夹可不会让你画技提升,究其原因还是因为干货缺少了理论上的指导,导致众多小可爱知其然不知其所以然。为此今天就分享了一套人体动态练习图,搭配讲解食用你还怕学不会吗?顺便推荐大家可以搜一下:灵猫课堂,或者打开手机微信,添加好友框内搜索:灵猫课堂,一键关注,学习无忧!上面..._人体体块怎么画

C语言字符串操作总结大全(超详细)_复制指定长度字符串-程序员宅基地

文章浏览阅读513次。1)字符串操作 strcpy(p, p1) 复制字符串 strncpy(p, p1, n) 复制指定长度字符串 strcat(p, p1) 附加字符串 strncat(p, p1, n) 附加指定长度字符串 strlen(p) 取字符串长度 strcmp(p, p1) 比较字符串 strcasecmp忽略大小写比较字符串strncmp(p, p1, n) 比较指定长_复制指定长度字符串

宝塔的防火墙是什么?有什么作用呢?_宝塔系统防火墙是什么防护-程序员宅基地

文章浏览阅读1.4w次。宝塔想必大家一定很熟悉了,用过服务器的都知道。那今天给大家介绍下宝塔的防火墙。宝塔面板网站防火墙是基于nginx/apache模块开发的一套应用层防火墙,能有效阻止大部分渗透攻击,且提供高度自由的规则自定义功能,为站点加一道铜墙铁壁。主要目的是从源头阻止站点被挂马的事情发生。目前宝塔官网和官方论坛一直都在使用宝塔网站防火墙,效果良好。宝塔面板防火墙是一个防火墙程序,用于在宝塔面板中防御服务器外来攻击使用的。根据环境服务软件的不同,分为nginx防火墙和apache防火墙。宝塔面板防火墙其实管理的是操_宝塔系统防火墙是什么防护

推荐文章

热门文章

相关标签