在Java中动态传参调用Python脚本
最近,又接触到一个奇葩的接口,基于老板不断催促赶时间的情况下,在重写java接口和复用已有的python脚本的两条路中选择了后者,但是其实后者并没有好很多,因为我是一个对python的认识仅限于其名称拼写的人,所以,我将把我这一天内从配置环境到最终刚成功调用脚本的过程整理一下,分享给大家。
首先,我先大体上整理一下我的思路(以下以py代替python):
1. py脚本如何运行?
2. java中如何调用py脚本?
3. 如何在java中向py脚本中动态传参。
4. 运行发布
接下来,我将顺着以上三个方面的思路来分别介绍,并展示我因此踩过的坑。
一、 py脚本如何运行?
- 第一步当然是学习所有的语言都必备的:安装环境,此处不再赘述,给大家一个我参考的博客,非常详细。windows下python环境的安装
包括了安装环境到简单的运行语句等内容。 - 这样的话,我在本地已经可以运行出已经写好的py程序。
- 注意:这是我踩的第一个坑,在配置python环境时,要注意你当前运行的py脚本的版本,因为2.7和3.0两个版本的兼容不是很好,所以环境配置不相同时,可能会导致写好的py脚本出现语法错误,所以要注意这一点,选择相应版本的安装包。
二、java中如何调用py脚本?
关于java中如何调用py脚本,网上一搜就有很多种方法,我主要实践了其中两种,当然最后采用的一种也是有原因的,下文会详细解释。
1. 第一种,Jython
什么是jython?
他其实是一门语言,并非是Java 或者Python的解释器.用它可以实现,java和python代码的互相访问。
如何使用jython?
如何使用Jython
所需jar包:
为什么最终没有选择使用jython?
这是我踩过的第二个坑,上面引用的的jython教程,几个例子都能很好的运行,函数传参也非常方便,但在运行现有的demo.py时,却一直在报下面这个错:
查询过后,发现是java项目中引包不全的问题,但是基于我对py的了解之少,我放弃了这个集成好的方法,毕竟需要一点对py的了解。这个等以后有时间再做研究。
2.于是在放弃jython之后,我还是采用了java自带的命令行执行py Runtime.getRuntime().exec(args),然后采用输出流的方式用来获取参数。
在封装好的py脚本的情况下,如果你不需要传入参数而只需要执行这个py文件的话,那么直接百度就可以获取得到很多写好的代码,我这里提供一种我这次使用的:
try {
Process pr = Runtime.getRuntime().exec("python G:\\test.py");
BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
line = decodeUnicode(line);
System.out.println(line);
}
in.close();
pr.waitFor();
System.out.println("end");
} catch (Exception e) {
e.printStackTrace();
}
然后看到这里,只需要修改Runtime.getRuntime().exec(“”)中的参数改为自己相应的文件路径即可,就可以轻松结束本次分享,但是,总有但是,我们大多数情况下调用一个复用的部分,都是为了传入不同的参数以获取相应的结果,那么请继续往下看。
三、如何在java中向py脚本中动态传参。
- 首先,先来一起明确一个概念,向脚本中动态传参,我一开始就很难理解,一个java的参数如何转为py的参数呢?但是,脚本就是可以直接用命令行运行的,具体是什么意思呢?我也不太清楚,但是我在询问不同人的不同方法之下,找到了一种自己能够会用并且能够理解的方法。具体参见:Python获得命令行传参
- 那么一言不合上代码吧:
Java代码:
try {
//需传入的参数
String a = getPara("car").substring(1), b = "D3455054", c = "LJ12GKS28D4418248", d = "qingdao";
System.out.println("start;;;" + a);
//设置命令行传入参数
String[] args = new String[] { "python", "/api_test.py", a, b, c, d };
Process pr = Runtime.getRuntime().exec(args);
BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
line = decodeUnicode(line);
System.out.println(line);
}
in.close();
pr.waitFor();
System.out.println("end");
} catch (Exception e) {
e.printStackTrace();
}
py代码:
import sys
print "脚本名:", sys.argv[0]
for i in range(1, len(sys.argv)):
print "参数", i, sys.argv[i]
运行结果:
那么,酱紫就大功告成啦。你只需要根据py脚本中所需要的参数传进去就好啦。
运行发布
运行发布有什么好说的呢?
这里也有一点需要注意的,就是服务器环境的配置,linux一般都是集成好的,其他的我不太清楚,但是最重要的一点,在上线调试时,一定要注意py文件的路径存放问题。就酱。
总结
从一开始的完全摸不到头脑,到现在能够调用成功,这不到一天的时间,压力却是很大的,面对未知的知识,无从下手的感觉我想大家也都经历过,但在这里,我十分想感谢那些无私帮助我的旁友们~多交流一下,别人不一定有时间能帮你解决,但能够提供思路的情况下,就能够早一点找到正确的方向,比如”Python获得命令行传参“这个东西,我一开始真是连百度搜索什么都不知道,搜到的东西可能跟你需要的完全不搭边,那么有一个方向也是好的。当然,这个方向完全正确,奠定了后面动态传参能够成功的基础,哈哈。
这个博客只显示了我的一个特点:我不生产博客,我只是博客的搬运工~
附录:遗留问题
项目中获取到的中文参数,一向py脚本中传参就显示乱码,只有中文出现这个情况,到目前也没有找到解决方法,那么现在采用了一种曲线救国的方式,但是非常的不好,然而目前并没有发现更好的解决方法,放在这里待以后继续研究,或者大家能有什么好方法也希望能够多多交流~
原文地址:https://blog.csdn.net/thorny_v/article/details/61417386
在Java中动态传参调用Python脚本的更多相关文章
- java 中 Integer 传参方式的问题
Java本身都是值传递式的调用,对于对象传递的是地址值.给地址值重新赋值等于重新指向,不会影响外层. 而且这里Integer对象也有特殊性.其实现上可能类似 class Integer{ final ...
- Java的对象传参问题
在c/c++中对于传参类型,无外乎就是传值.传引用.传指针这几种.但在java中,由于没有指针类型,其传参的方式也发生了相应的变化.之前有搜过相关的知识点一直理解的是:Java的传参方式中主要有两种: ...
- linux+php+apache web调用python脚本权限问题解决方案
lamp : linux + apache + mysql + php 在上篇随笔中linux+php+apache调用python脚本时出现的问题的根本原因是:apache运行时使用的apache用 ...
- python函数的动态传参.作用域与命名空间
一.动态传参1.*表示动态传参. 可以接受所有的位置参数传参的时候自动的把实参打包成元组 交给形参 def chi(*food): print(food) chi() # 动态传参可以不传参数 chi ...
- python记录_day10 动态传参 命名空间 作用域
一.动态传参 动态传参用到 *args 和 **kwargs ,*号表示接收位置参数,args是参数名:**表示接收关键字参数,kwargs是参数名 def chi(*food): print(foo ...
- python(动态传参、命名空间、函数嵌套、global和nonlocal关键字)
一.函数的动态传参 1.*args位置参数动态传参 def chi(*food): print(food) chi("烧烤","火锅","虾吃虾涮&q ...
- 使用java传参调用exe并且获取程序进度和返回结果的一种方法
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 在某个项目中需要考虑使用java后台调用由C#编写的切图程序( ...
- 利用python执行shell脚本 并动态传参 及subprocess基本使用
最近工作需求中 有遇到这个情况 在web端获取配置文件内容 及 往shell 脚本中动态传入参数 执行shell脚本这个有多种方法 最后还是选择了subprocess这个python标准库 su ...
- python之路--动态传参,作用域,函数嵌套
一 . 动态传参(重点) * , ** * 与 ** * 在形参位置. * 表示不定参数, 接收的是位置参数 接收到的位置参数的动态传参: 都是元组 def eat(*food): # 在形参这里 ...
随机推荐
- abstract、virtual、sealed、 interface、struct 基础知识整理
abstract abstract 修饰符指示被修改内容的实现已丢失或不完整. abstract 修饰符可用于类.方法.属性.索引和事件. 在类声明中使用 abstract修饰符以指示某个类仅旨在作为 ...
- 大牛是怎么思考设计MySQL优化方案
在进行MySQL的优化之前,必须要了解的就是MySQL的查询过程,很多查询优化工作实际上就是遵循一些原则,让MySQL的优化器能够按照预想的合理方式运行而已. 1.优化的哲学 注:优化有风险,涉足需谨 ...
- Hashtable,HashMap,TreeMap有什么区别?Vector,ArrayList,LinkedList有什么区别?int和Integer有什么区别?
接着上篇继续更新. /*请尊重作者劳动成果,转载请标明原文链接:*/ /*https://www.cnblogs.com/jpcflyer/p/10759447.html* / 题目一:Hashtab ...
- CS231n官方笔记授权翻译总集篇发布
CS231n简介 CS231n的全称是CS231n: Convolutional Neural Networks for Visual Recognition,即面向视觉识别的卷积神经网络.该课程是斯 ...
- Redis持久化存储与复制功能简述
一.分布式系统基础理论 分布式系统的两个基础理论: 1.CAP理论 如图: Consistency(强一致性):数据一致更新,所有数据变动都是同步的.Availability(可用性):好的响应性能. ...
- [转]git操作指南
[GIT上手篇]-1-基本操作(初始化仓库,添加.提交文件) 创建(初始化)一个GIT库 init 命令 说明:用于仓库的初始化 参数:--bare 创建一个纯仓库(不含缓存区和工作目录,服务器一般采 ...
- 【SQL】小心在循环中声明变量——浅析SQL变量作用域
本文适用:T-SQL(SQL Server) 先看这个语句: --跑3圈 BEGIN --每圈都定义一个表变量,并插入一行 DECLARE @t TABLE(Col INT PRIMARY KEY) ...
- ELK日志分析平台系统CentOS7环境搭建和基本使用
一.搭建环境 系统环境:CentOS7 安装iptables:https://blog.csdn.net/momo_mutou/article/details/81739155 jdk1.8: ht ...
- 每个JavaScript工程师都应懂的33个概念
摘要: 基础很重要啊! 原文:33 concepts every JavaScript developer should know 译文:每个 JavaScript 工程师都应懂的33个概念 作者:s ...
- mysql远程连接 Host * is not allowed to connect to this MySQL server(第一次配置好lnmp环境)
1.第一次在linux上搭建好mysql,本机windows远程链接报错Host * is not allowed to connect to this MySQL server 2.原因:mysql ...