最近,又接触到一个奇葩的接口,基于老板不断催促赶时间的情况下,在重写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. 课程四(Convolutional Neural Networks),第四 周(Special applications: Face recognition & Neural style transfer) —— 1.Practice quentions

    [解释] This allows us to learn to predict a person’s identity using a softmax output unit, where the n ...

  2. eosio.cdt:EOS智能合约工具集

    目前EOS已经迎来了1.5.x时代,很多内容都有了较大的改变.其中智能合约的工作流程发生了改变,EOSIO为智能合约提供了独立且功能完整的工具集eosio.cdt.该工具集基于WASM平台,可解耦于e ...

  3. centos6.10搭建ELK之elasticsearch6.5.4

    1.环境准备 1.1.安装java环境版本不要低于java8 # java -version java version "1.8.0_191" Java(TM) SE Runtim ...

  4. MySQL 事务机制

    事务处理是保证数据安全的重要机制,事务有四个重要属性 ,根据它们的英文名称可以记为ACID: 原子性(Atomic): 事务操作是不可分割的; 事务只存在已执行和未执行两种状态,不存在只执行了部分指令 ...

  5. Linux 命令行下光标移动快捷键

    常用的快捷键: Ctrl + u 删除光标之前到行首的字符 Ctrl + k 删除光标之后到行尾的字符 Ctrl + a 光标移动到行首 Ctrl + e 光标移动到行尾 Ctrl + l 清屏 Al ...

  6. 深入浅出 JVM GC(2)

    # 前言 在 深入浅出 JVM GC(1) 中,限于上篇文章的篇幅,我们留下了一个问题 : 如何回收? 这篇文章将重点讲述这个问题. 在上篇文章中,我们也列出了一些大纲,今天我们就按照那个大纲来逐个讲 ...

  7. 弱引用(WeakReference)

    在应用程序代码内实例化一个类或结构时,只要有代码引用它,就会形成强引用.这意味着垃圾回收器不会清理这样的对象使用的内存.但是如果当这个对象很大,并且不经常访问时,此时可以创建对象的弱引用,弱引用允许创 ...

  8. Topshelf 学习 跨平台【转载】

    Topshelf 学习 跨平台   Topshelf是一个开源的跨平台的宿主服务框架,支持Windows和Mono,只需要几行代码就可以构建一个很方便使用的服务宿主. 官网:http://topshe ...

  9. Ubuntu安装SSH SERVER

    apt-get update apt-get install openssh-server 安装好后查看SSH是否启动 打开”终端窗口”,输入”sudo ps -e |grep ssh“–>回车 ...

  10. java-上转型对象&抽象类-学习记录

    上转型对象: 如果B类是A类的子类(或间接子类),当用子类创建对象b并将这个对象的引用放到父类对象a中时,如: A a; a = new b() 或 A a;B b = new B();a = b; ...