最近,又接触到一个奇葩的接口,基于老板不断催促赶时间的情况下,在重写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. TODO:数据库优化之分页

    TODO:数据库优化之分页 本文的例子是以MongoDB数据库为准,其它数据库各位也可以举一反三进行优化. 在MongoDB中分页使用 a.skip(n)跳过前n个匹配的文档: b.limit(m)返 ...

  2. Leetcode 69. Sqrt(x)

    Implement int sqrt(int x). 思路: Binary Search class Solution(object): def mySqrt(self, x): "&quo ...

  3. ListView的item选中效果

    有时app会需要点击某个item并实现选中的效果,例如做pad时用Fragment实现的左侧列表右侧内容的效果,点击左侧某一个item后会高亮选中 有时简单的使用setSelected(boolean ...

  4. Struts2系列——struts2的result

    在action的指定方法执行完毕后总会返回一个字符串,struts2根据返回的字符串去action的配置中的result去找匹配的名字,根据配置执行下一步的操作. 在ActionSupport基类中定 ...

  5. HTML <base> 标签的 target 属性 —— <base target="_blank" />

    为页面上所有链接规定默认目标: <head> <base target="_blank" /> </head> <body> < ...

  6. ActionBar官方教程(7)自定义操作项的view,如何得到它及处理它的事件

    Adding an Action View An action view is a widget that appears in the action bar as a substitute for ...

  7. Java编程思想第四版*第七章*个人练习

    欢迎加群:239063848 成团的笔记:该组仅用于技术共享和交流,问题和答案公布 潘基聊天.禁止广告.禁止招聘-- 练习1:(2)创建一个简单的类.第二个类中,将一个引用定义为第一个类的对象.运用惰 ...

  8. python初探-copy

    python中,数据的拷贝有以下三种形式:赋值.浅copy和深copy.根据类型的不同,可以把数据分成以下两类:字符串和数字为一类,其他(包括列表.元祖.字典...)为一类. 在python中有池的概 ...

  9. docker+tomcat 启动时非常慢原因之JRE /dev/random阻塞

    docker+tomcat 启动时非常慢,一般正常启动几十秒的,发现docker+tomcat启动竟需要几分钟,不可思议 根本原因是 SecureRandom 这个 jre 的工具类的问题.那为什么 ...

  10. 【转载】JavaScript基础知识体系

    前言 最近总是有一种感觉,对于知识没有积淀,很多时候都是忘记了哪里就去查一下,比如JS这种语言,很是浪费时间,如果能够把这些知识形成知识体系塞进大脑,做到即用即取就好了,那么就可以借助思维导图来帮助我 ...