最近,又接触到一个奇葩的接口,基于老板不断催促赶时间的情况下,在重写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. python(动态传参、命名空间、函数嵌套、global和nonlocal关键字)

    一.函数的动态传参 1.*args位置参数动态传参 def chi(*food): print(food) chi("烧烤","火锅","虾吃虾涮&q ...

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

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

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

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

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

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

随机推荐

  1. 关于小窗滑动,父级body也跟随滑动的解决方案

    需求:当前页面是信息列表,所以高度由内容自动填充, 所以页面可以上下滑动,加载更多, 但是下发物料一栏又为一个列表 所以做了一个弹窗框,因为是列表所以高度自然又是不可控的,所以给了一个最大高度,当超出 ...

  2. Android动态添加Fragment

    Android动态添加Fragment 效果图如下: 项目结构图如下: Fragment1: package com.demo.dongtaifragment; import android.app. ...

  3. springboot将项目源代码打包

    springboot将项目源代码打包并发布到仓库 如果我们有一些类和方法是公用的,可以打开公用包,而这时使用默认的build方式都所有依赖都打进去,而且你当然项目的文件虽然在包里,但却在boot-in ...

  4. 手把手教你学会用Spring AOP

    用了Spring很长时间了,一直想写些AOP的东西,但一直没有空闲,直到现在项目稍微进入正轨了,才赶紧写写.废话不多说,先从AOP入门开始,后面再介绍AOP的原理(JDK动态代码和CGLIB动态代码的 ...

  5. C语言指针基本操作

    C语言指针基本操作 指针  指针介绍 如果说C语言最有魅力的地方在哪,那么毋庸置疑,非指针莫属了. 众所周知,C语言中每个变量都有一个内存地址,可以通过&进行访问.指针是一个变量,它的值是一个 ...

  6. 一个复杂Json的解析

    { "website": { "1": { "basic": { "homepage": "http://py ...

  7. c++中虚函数和多态性

    1.直接看下列代码: #include <iostream> using namespace std; class base{ public: void who(){ cout<&l ...

  8. sql 去掉 空格

    一.问题描述: 数据库中字段 nvarchar类型 存放数据如下: '3.3×10' 二.解决方案: --测试用例CREATE TABLE #temp(NAME NVARCHAR(20) null) ...

  9. [PHP] 数据结构-单链表头插法PHP实现

    1.创建头结点 2.创建新结点 3.新结点next指向头结点next 4.头结点next指向新结点 <?php class Node{ public $data; public $next; } ...

  10. music-api-next:一款支持网易、xiami和QQ音乐的JS爬虫库

    音乐,无界 让音乐无界 如果你苦于挑选一个全方位.多平台.简便易用的音乐爬虫库,music-api-next是不二选择. 特性: 支持网易.虾米和QQ三大主流音乐平台 支持音乐关键词搜索 支持音乐链接 ...