• java调用python脚本


    java调用python脚本

     

    常见的java调用python脚本方式

    • 通过jython.jar提供的类库实现 (不建议使用,因为会报module没有找到的错误,总之就是很蛋疼,要设置一系列的参数)
    • 通过Runtime.getRuntime()开启进程来执行脚本文件(建议使用,原因:简单粗暴我喜欢!!!)在这个里面注意:调用py脚本的时候,先用windows的dos界面去运行下 命令: python xxxx.py,测试,脚本可以调用,不然可能在java脚本就是调用了,但是就是失败了的情况,导致一直卡住,本人就是这样的一个情况。卡了两天。。。。。。

    通过jython.jar提供的类库实现

    通过jython.jar实现的话,我们需要引入jar包,具体我写了一个demo,假设你的python代码为test.py:

    defmy_test(name, age):
        print("name: "+name)
        print("age: "+age)
        return "success"
    • 1
    • 2
    • 3
    • 4

    java调用test.py代码:

    public static void main(String[] args) {
          PythonInterpreter interpreter = new PythonInterpreter();  
          interpreter.execfile("E:\workspace\pycharm_workspace\weixincrawer\test.py");  
          PyFunction function = (PyFunction)interpreter.get("my_test",PyFunction.class);  
          PyObject pyobject = function.__call__(new PyString("huzhiwei"),new PyString("25")); 
          System.out.println("anwser = " + pyobject.toString());  
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    输出结果:

    name: huzhiwei
    age:25
    anwser = success
    • 1
    • 2
    • 3

    到此是没有什么问题的,我们使用function.call方法传入参数调用python函数,使用pyobject.toString()方法拿到python中my_test函数的返回值,但是如果你把test.py稍微做下修改如下:

    import requests
    
    defmy_test(name, age):
        response = requests.get("http://www.baidu.com")
        print("name: "+name)
        print("age: "+age)
        return "success"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    不修改java调用代码的情况下,你会得到下面异常信息:

    ImportError: No modulenamedrequests
    • 1

    没错,这就是我要讨论的问题,因为jython不可能涵盖所有python第三方类库的东西,所以在我们得python文件中用到requests类库的时候,很显然会报找不到模块的错误,这个时候我们是可以通过Runtime.getRuntime()开启进程来执行python脚本文件的。

    通过Runtime.getRuntime()开启进程来执行脚本文件

    使用这种方式需要同时修改python文件以及java调用代码,在此我同样在上面test.py的基础上进行修改:

    import requests
    import sys
    
    defmy_test(name, age):
        response = requests.get("http://www.baidu.com")
        print("url:"+response.url)
        print("name: "+name)
        print("age: "+age)
        return "success"
    
    my_test(sys.argv[1], sys.argv[2])
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    和上面test.py代码最大的区别在于,我们此处开启进程的方式实际上是在隐形的调用dos界面进行操作,因此在python代码中我们需要通过sys.argv的方式来拿到java代码中传递过来的参数。

    java调用代码部分:

    publicstaticvoidmain(String[] args) {
          String[] arguments = new String[] {"python", "E:\workspace\pycharm_workspace\weixincrawer\test.py", "huzhiwei", "25"};
            try {
                Process process = Runtime.getRuntime().exec(arguments);
                BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
                String line = null;  
              while ((line = in.readLine()) != null) {  
                  System.out.println(line);  
              }  
              in.close();  
              int re = process.waitFor();  
              System.out.println(re);
            } catch (Exception e) {
                e.printStackTrace();
            }  
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    结果输出:

    url:http://www.baidu.com/
    name: huzhiwei
    age: 25
    0
    • 1
    • 2
    • 3
    • 4

    在此需要注意的一点,java代码中的process.waitFor()返回值为0表示我们调用python脚本成功,返回值为1表示调用python脚本失败,这和我们通常意义上见到的0与1定义正好相反。

     

     

    转载自:https://blog.csdn.net/hzw19920329/article/details/77509497

     
  • 相关阅读:
    Eureka的使用
    自定义类加载器
    继承
    Active Objects模式
    Future设计模式
    mysql备份与还原
    多生产者多消费者(第一种方式),基于synchronized,wait,notifyAll
    自己实现阻塞队列(基于数组)
    linux定时任务每隔5分钟向文本追加一行
    自己实现CountDownLatch
  • 原文地址:https://www.cnblogs.com/di2wu/p/10447242.html
Copyright © 2020-2023  润新知