java执行python脚本_通过Java调用Python脚本
在进行开发的过程中,偶尔会遇到需要使用Java调用Python脚本的时候,毕竟Python在诸如爬虫,以及科学计算等方面具有天然的优势。最近在工作中遇到需要在Java程序中调用已经写好的Python程序,故做一下记录。
1常用的Java调用Python脚本的两种方式
调用方式通常为以下两种:
•通过Jython调用,即通过Jython.jar提供的类库实现
•直接通过Java的Runtime实现,Runtime类的Runtime.getRuntime()开启进程,执行python脚本文件
2通过Jython实现调用
Jython简介
Jython主页:http://www.jython.org/
Jython是Python语言在Java平台的实现,本质上,Jython是由Java编写,其是在JVM上实现的Python语言。因此,可以直接通过Jython在Java中调用Python。
Jython安装
在安装Jython之前,必须确保本地已经安装了JDK。
1. 通过Jython的官网下载对应版本的安装文件Installer和单独的standalone jar两个jar文件,放到特定的目录下,如C:jython2.7.0;
2. 进入终端,切换到当前用于安装Jython的jar文件所在的目录下,执行java -jar jython_installer_2.7.0.jar,「当然也可以直接进入目录双击对应的jar文件进行安装」;
3. 配置对应的环境变量,分别将对应的jar,lib目录加到CLASSPATH和Path中:
–C:jython2.7.0jython.jar; 加入到CLASSPATH中
–C:jython2.7.0;C:jython2.7.0Lib;加入到Path中
此时在终端下执行jython命令,如果安装成功,则会进入到Jython的交互环境,可与Python的交互环境一样执行Python命令。同时也可以通过jython xxx.py命令执行python脚本文件。
Jython执行Python脚本
直接在Java中嵌入Python语句
在Java中直接嵌入Python语句的用法较少,且实际意义不大。
import org.python.util.PythonInterpreter;
public class Main {
public static void main(String[] args) {
PythonInterpreter interpreter = new PythonInterpreter();
//执行Python语句
interpreter.exec("import sys");
interpreter.exec("print 'hello'");
interpreter.exec("print 2**100");
}
}
在Java中执行已经编写好的名为xxx.py的 Python脚本
直接通过Jython包调用写好的Python脚本,根据程序执行时的要求,大体可以分为以下几种情况:
1.不需要通过Java程序向Python脚本中传递参数,也不需要获取Python脚本之行后的返回值,则可以通过文件流的方式直接打开脚本,并使用Jython的解释器执行。
import org.python.util.PythonInterpreter;
import java.io.*;
public class Main {
public static void main(String[] args) {
PythonInterpreter interpreter = new PythonInterpreter();
//执行Python脚本文件
try {
InputStream filepy = new FileInputStream("C:xxx.py");
interpreter.execfile(filepy);
filepy.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.在Java中调用Python程序,同时需要传递参数和接收返回值。调用Python程序中的方法,可分为两种,一种是直接调用Python中写好的方法函数,另一种则是调用Python脚本的类中的函数。
–直接调用函数,通过PyFunction实现参数的传递和返回值的获取
import org.python.core.*;
import org.python.util.PythonInterpreter;
public class Main{
public static void main(String[] args) {
PythonInterpreter inter = new PythonInterpreter();
//指定Python函数文件的路径
String pythonFunc = "D:test.py";
inter.execfile(pythonFunc);
//获取函数名test
PyFunction pyf = inter.get("test", PyFunction.class);
//向函数中传递参数并获取返回结果
PyObject res = pyf.__call__(Py.newInteger(2), Py.newInteger(3));
System.out.print(res);
inter.cleanup();
inter.close();
}
}
– 在Java中调用Python对象实例方法,使用PyObject方法实例化Python对象,调用Python对象方法,传递参数并切接收返回值。
import org.python.core.*;
import org.python.util.PythonInterpreter;
public class Main{
public static void main(String[] args) {
PythonInterpreter inter = new PythonInterpreter();
//python类路径
String pythonClass = "D:test_class.py";
//python 对象名
String pythonObjName = "cal";
// python类名
String pythonClazzName = "Calculator";
inter.execfile(pythonClass);
//实例化Python对象
inter.exec(PythonObjName + "=" + pythonClazzName + "()");
//获取实例化的Python对象
PyObject pyObject = inter.get(pythonObjName);
//调用python对象方法,传递参数并接收返回值
PyObject res = pyObject.invoke("power", new PyObject[] {Py.newInteger(2), Py.newInteger(3)});
double power = Py.py2double(res);
System.out.print(power);
inter.cleanup();
inter.close();
}
}
其中,test_class.py文件的内容如下:
import math
class Calculator(object):
def power(x, y):
return math.pow(x, y)
通过Runtime.getRuntime().exec()实现调用
Runtime类是Java中一个与JVM运行时环境有关的类,通过Runtime.getRuntime()可以获取到当前JVM运行时的环境。Runtime上的大部分方法都是实例方法,即每次在进行运行时调用时都要用到getRuntime()方法。使用Runtime类执行Python脚本的方法非常简单粗暴,直接传入当前平台下的Python脚本执行命令即可。Java执行外部命令,主要方式还是使用Runtime类的exec()方法调用平台shell完成,如windows下的cmd,以及linux、unix、macOS下的的shell。
通过Runtime执行Python脚本,可以直接通过命令向脚本中传递参数,并获取Python脚本的输出。
public class Main{
public static void main(String[] args) {
String cmd = "python xxx.py argv1 argv2 ...";
Process proc = Runtime.getRuntime().exec(cmd);
InputStream is = proc.getInputStream();
DataInputStream dis = new DataInputStream(is);
String str = dis.readLine();
proc.waitFor();
System.out.println(str);
}
}
3总结
以上两种方法都可以实现在Java程序中调用Python脚本,但使用Jython进行调用时,效率较低,也会消耗较多资源,且调用的脚本需要Python的第三方依赖包时,需要在Jython中安装第三方包。而使用Runtime调用脚本时,更多的依赖于运行的平台,只要当前平台安装了对应的第三方依赖包,脚本就可以顺利执行,执行效率和直接执行Python脚本并没有区别。
当然,在程序中不断的进行嵌套调用,会降低程序的执行效率,增加程序的耦合复杂度,不方便将来的扩展,因此并不建议大家经常使用,而可以考虑通过微服务的方法解决对应的问题。
文章还有很多不足之处,希望大家多多交流,多多指教。
参考链接
1.五大基于JVM的脚本语言https://coolshell.cn/articles/2631.html
2.Java调用Python http://tonl.iteye.com/blog/1918245
3.Java Runtime.exec()的使用https://blog.csdn.net/toneylyx/article/details/52623597
4.Why are there so many pythons https://www.oschina.net/translate/why-are-there-so-many-pythons
5.Jython www.jython.org
java执行python脚本_通过Java调用Python脚本相关推荐
- java执行shell命令权限不够_Java调用shell脚本解决传参和权限问题的方法|chu
1. java 执行shell java 通过 Runtime.getRuntime().exec() 方法执行 shell 的命令或 脚本,exec()方法的参数可以是脚本的路径也可以是直接的 sh ...
- php 与 python对接_关于PHP调用Python的实施以及配置
这是一份经过实验而来的经验总结,在试验的过程中曾经思考采用CGI的方式.毕竟是在windows的环境下,未能在linux的环境下测试CGI的方案是否可靠.可喜的是,通过CGI方案的配置后最终实现了PH ...
- Java执行引擎工作原理:方法调用
Java执行引擎工作原理:方法调用 方法调用如何实现 函数指针和指针函数 CallStub源码详解 Git链接(有HotSpot源码) 1 方法调用如何实现 计算机核心三大功能:方法调用.取指.运算 ...
- java项目----教务管理系统_基于Java的教务管理系统
java项目----教务管理系统_基于Java的教务管理系统 2022-04-22 18:18·java基础 最近为客户开发了一套学校用教务管理系统,主要实现学生.课程.老师.选课等相关的信息化管理功 ...
- hive运行mysql脚本_用java代码调用shell脚本执行sqoop将hive表中数据导出到mysql
1:创建shell脚本 1 touch sqoop_options.sh2 chmod 777 sqoop_options.sh 编辑文件 特地将执行map的个数设置为变量 测试 可以java代码 ...
- java运行python脚本_用Java运行Python脚本
我正在尝试在执行我的java代码期间运行python脚本,因为它将取决于从python脚本接收的输出.到目前为止,我尝试使用jythonc,遗憾的是没有成功,现在我试图使用java Runtime和j ...
- java 执行javascript_说说如何在 Java 中执行 JavaScript 脚本
Java 是强类型的静态语言,即所有的代码在运行之前都必须先进行严格的类型检查并编译为 JVM 字节码.这样做虽然保证了安全与性能,但却牺牲了灵活性.而那些动态语言(JavaScript .Pytho ...
- java 易变变量_提高java编程质量 - (一)易变业务使用脚本语言编写
脚本语言的3大特征: 1.灵活:脚本语言一般是动态类型,可以不声明变量类型直接使用,也可以在运行期改变类型: 2.便捷:脚本语言是解释性语言,在运行期变更非常方便,而不用重启服务 3.简单:脚本语言语 ...
- java bat 启动脚本_解析Tomcat的启动脚本--catalina.bat
概述 Tomcat 的三个最重要的启动脚本: startup.bat catalina.bat setclasspath.bat 上一篇咱们分析了 startup.bat 脚本 这一篇咱们来分析 ca ...
最新文章
- 15分钟带你入门sklearn与机器学习——分类算法篇
- 最新版 | 2020李沐《动手学深度学习》
- VS2013打包VC++程序
- mysql数据库实验3查询_MySQL数据库实验:任务三 数据库的单表查询设计
- 并发编程-08安全发布对象之发布与逸出
- 【工作感悟】java编程规范pdf下载
- 多线程实现的4中方法
- golang使用pprof检查goroutine泄露
- mysql多表条件查询,mysql实现RBAC权限管理sql语句详解
- 图像识别与软件自动化测试
- 操作系统课程设计 —— 模拟磁盘文件系统实现 (Java)
- matlab 平滑曲线连接_从零开始的matlab学习笔记——(16)函数绘图
- 电子智能化专包有哪些要求和标准
- 备战数学建模36-时间序列模型2
- Django项目报错记录1
- 9:JDBC-Java API 实战
- 自学IT后的第一篇博文
- 如何删除Facebook评论
- 凡事预则立不预则废---20180112
- STM32彩灯控制器
热门文章
- 网站被植入Webshell的解决方案
- CentOS7.9 Nvidia驱动安装
- 贝叶斯分位数回归、lasso和自适应lasso贝叶斯分位数回归分析免疫球蛋白、前列腺癌数据...
- 定义一个DataType(数据类型)类,能处理包含字符型、整型、浮点型三种类型的数据,给出其构造函数。
- mysql 实现类似 postgresql 数据库的 generate_series 函数
- CSS的expression
- 《Oracle 入门教程》第 01 篇 专栏介绍
- LuaXml在打印CDATA时,失效了,被转义了
- C#QuotedStr方法实现,引号的处理
- useradd: warning: the home directory already exists. Not copying any file from skel directory intoit