最近,又接触到一个奇葩的接口,基于老板不断催促赶时间的情况下,在重写java接口和复用已有的python脚本的两条路中选择了后者,但是其实后者并没有好很多,因为我是一个对python的认识仅限于其名称拼写的人,所以,我将把我这一天内从配置环境到最终刚成功调用脚本的过程整理一下,分享给大家。


首先,我先大体上整理一下我的思路(以下以py代替python): 
1. py脚本如何运行? 
2. java中如何调用py脚本? 
3. 如何在java中向py脚本中动态传参。 
4. 运行发布

接下来,我将顺着以上三个方面的思路来分别介绍,并展示我因此踩过的坑。

一、 py脚本如何运行?

  1. 第一步当然是学习所有的语言都必备的:安装环境,此处不再赘述,给大家一个我参考的博客,非常详细。windows下python环境的安装 
    包括了安装环境到简单的运行语句等内容。
  2. 这样的话,我在本地已经可以运行出已经写好的py程序。
  3. 注意:这是我踩的第一个坑,在配置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脚本中动态传参。

  1. 首先,先来一起明确一个概念,向脚本中动态传参,我一开始就很难理解,一个java的参数如何转为py的参数呢?但是,脚本就是可以直接用命令行运行的,具体是什么意思呢?我也不太清楚,但是我在询问不同人的不同方法之下,找到了一种自己能够会用并且能够理解的方法。具体参见:Python获得命令行传参
  2. 那么一言不合上代码吧: 
    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脚本的更多相关文章

  1. java 中 Integer 传参方式的问题

    Java本身都是值传递式的调用,对于对象传递的是地址值.给地址值重新赋值等于重新指向,不会影响外层. 而且这里Integer对象也有特殊性.其实现上可能类似 class Integer{ final ...

  2. Java的对象传参问题

    在c/c++中对于传参类型,无外乎就是传值.传引用.传指针这几种.但在java中,由于没有指针类型,其传参的方式也发生了相应的变化.之前有搜过相关的知识点一直理解的是:Java的传参方式中主要有两种: ...

  3. linux+php+apache web调用python脚本权限问题解决方案

    lamp : linux + apache + mysql + php 在上篇随笔中linux+php+apache调用python脚本时出现的问题的根本原因是:apache运行时使用的apache用 ...

  4. python函数的动态传参.作用域与命名空间

    一.动态传参1.*表示动态传参. 可以接受所有的位置参数传参的时候自动的把实参打包成元组 交给形参 def chi(*food): print(food) chi() # 动态传参可以不传参数 chi ...

  5. python记录_day10 动态传参 命名空间 作用域

    一.动态传参 动态传参用到 *args 和 **kwargs ,*号表示接收位置参数,args是参数名:**表示接收关键字参数,kwargs是参数名 def chi(*food): print(foo ...

  6. 使用java传参调用exe并且获取程序进度和返回结果的一种方法

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 在某个项目中需要考虑使用java后台调用由C#编写的切图程序( ...

  7. 利用python执行shell脚本 并动态传参 及subprocess基本使用

    最近工作需求中 有遇到这个情况  在web端获取配置文件内容 及 往shell 脚本中动态传入参数 执行shell脚本这个有多种方法   最后还是选择了subprocess这个python标准库 su ...

  8. python之路--动态传参,作用域,函数嵌套

    一 . 动态传参(重点)  * ,  ** * 与 ** * 在形参位置. * 表示不定参数, 接收的是位置参数 接收到的位置参数的动态传参: 都是元组 def eat(*food): # 在形参这里 ...

  9. Python中的传参是传值还是传址?

    传值:在C++中,传值就是把一个参数的值给这个函数,其中的更改不会影响原来的值. 传址:即传引用,直接把这个参数的内存地址传递进去,直接去这个内存地址上进行修改. 但是这些在Python中都没有,Py ...

随机推荐

  1. Odoo 二次开发教程(五)-新API的介绍与应用

    [关于odoo新API的介绍,Internet上资料很少,或者不够完整详实,这会对初学者造成很大的困惑,本篇的目的就是希望能帮助新手了解新API的大概] odoo 新api的实现是借助于python装 ...

  2. Spring学习总结(三)——Spring实现AOP的多种方式

    AOP(Aspect Oriented Programming)面向切面编程,通过预编译方式和运行期动态代理实现程序功能的横向多模块统一控制的一种技术.AOP是OOP的补充,是Spring框架中的一个 ...

  3. nios II--实验1——hello_world硬件部分

    hello_world 硬件开发 新建原理图 1.打开Quartus II 11.0,新建一个工程,File -> New Project Wizard…,忽略Introduction,之间单击 ...

  4. JDE910笔记1--基础介绍及配置[转]

    1.一般JDE部署后环境: DV:开发环境 PY:测试环境 PD:正式环境 根据端口号区分不同环境,可配置.同时,JDE默认使用分发服务器,不同环境连接为不同的数据库. 2.命名规范: 自定义项目.函 ...

  5. phpstudy 下开启openssl

    1.在php.ini里面的extension=php_openssl.dll是开启的状态,没有被注释. 2.里面的allow_url_fopen = On表示开启了. 3.如果你是Windows 64 ...

  6. Android用户界面 UI组件--TextView及其子类(三) EditView以及各种Span文字样式讲解

    EditView和TextView的用法差不多,只是文字可编辑 小技巧: 设置EditText隐藏键盘  setInputType(0); 设置EditText不被输入法遮盖  getWindow() ...

  7. 【HDOJ】3459 Rubik 2×2×2

    模拟+DFS. /* 3459 */ #include <cstdio> #include <cstring> #include <cstdlib> #define ...

  8. Oracle RAC环境下定位并杀掉最终阻塞的会话-续

    之前在<Oracle RAC环境下定位并杀掉最终阻塞的会话>中,最终使用一个SQL查询出RAC实例之间的所有阻塞关系.但是实际在某些极端的生产环境,是不允许执行复杂的SQL语句,即使允许执 ...

  9. JavaEE 之 后台验证+拦截器

    1.Validator后台验证 a.在web.xml中配置 <listener> <listener-class>org.springframework.web.context ...

  10. 利用Python+163邮箱授权码发送邮件

    背景 前段时间写了个自动打卡的脚本,但是脚本不够完善,我需要知道,打卡到底成没成功,因此,我想到了用Python执行完代码之后,再执行一段发送邮件的代码.需求开始明确了,就开始分析和写代码实现吧. 分 ...