Java执行python脚本

1.通过Jython实现调用

Jython简介

Jython主页:http://www.jython.org/

Jython是Python语言在Java平台的实现,本质上,Jython是由Java编写,其是在JVM上实现的Python语言。因此,可以直接通过Jython在Java中调用Python。

到官网https://www.jython.org/download.html下载Jython的jar包或者在maven的pom.xml文件中加入如下代码:

<dependency>
   <groupId>org.python</groupId>
   <artifactId>jython-standalone</artifactId>
   <version>2.7.0</version>
</dependency>

2.通过Java的Runtime实现

直接通过Java的Runtime实现,Runtime类的Runtime.getRuntime()开启进程,执行python脚本文件

3.示例

@RunWith(SpringRunner.class)
@SpringBootTest
public class JythonExampleApplicationTests {

    /**
     * Jython 在java类中直接执行python语句
     */
    @Test
    public void test0() {
        PythonInterpreter interpreter = new PythonInterpreter();
        interpreter.exec("a='hello world'; ");
        interpreter.exec("print a;");
    }

    /**
     * Jython 执行python文件
     */
    @Test
    public void test1() {
        /*************python***************
             #coding=utf-8
             print("hello world")
         **********************************/
        /*************python***************
             #coding=utf-8
             def greeting(name):
                 print("你好, " + name)
                 return "你好, " + name
             greeting("lnn");
         **********************************/
        PythonInterpreter interpreter = new PythonInterpreter();
        interpreter.execfile("D:\\fun.py");
    }

    /**
     * Jython 执行python文件,调用python方法
     */
    @Test
    public void test2() {
        /*************python***************
             #coding=utf-8
             def greeting(name):
                print("你好, " + name)
                return "你好, " + name
        ***********************************/
        PythonInterpreter interpreter = new PythonInterpreter();
                // 加载python脚本
        interpreter.execfile("D:\\fun.py");
        // 第一个参数为期望获得的函数(变量)的名字,第二个参数为期望返回的对象类型
        PyFunction pyFunction = interpreter.get("greeting", PyFunction.class);
        String name = "wsl";
        //调用函数,如果函数需要参数,在Java中必须先将参数转化为对应的“Python类型”
        PyObject pyobj = pyFunction.__call__(new PyString(name));
        //这里ret可能会乱码
        String ret = pyobj.toString();
        try {
            String newStr = new String(ret.getBytes("iso8859-1"), "utf-8");
            System.out.println("the anwser is: " + newStr);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        // 报错unindent does not match any outer indentation level
        // python对缩进具有严格的要求
        // 1、代码前后缩进量不一致
        // 2、代码前后缩进符号不一致
        // 3、tab与space混用
        // 报错SyntaxError: Non-ASCII character in file
        // 1, 出现的原因: python的默认编码文件是用ASCII码,没有支持UTF-8,而你的python文件中使用了中文等非英语字符。
        // 2,因此,解决的方法,在文件的开头输入如下:
        // # -*- coding: UTF-8 -*-    或者  #coding=utf-8
    }

    /**
     * Jython 执行python文件,引用自定义python模块
     */
    @Test
    public void test3() {
        /*************python***************
             #coding=utf-8
             import fun
             def add(a,b):
                 fun.greeting(str(a))
                 fun.greeting(str(b))
                 return a + b
             fun.greeting("wsl")
         **********************************/
        //System.setProperty("python.home", "D:\\tools\\python");
        PythonInterpreter interpreter = new PythonInterpreter();
        // 引用自定义python模块
        PySystemState sys = Py.getSystemState();
        sys.path.add("D:\\py_test");//import 模块的文件目录
        interpreter.exec("import fun");//添加模块引用 es: import fun
        // 加载python脚本
        interpreter.execfile("D:\\py_test\\add.py");
        // 第一个参数为期望获得的函数(变量)的名字,第二个参数为期望返回的对象类型
        PyFunction pyFunction = interpreter.get("add", PyFunction.class);
        int a = 5, b = 10;
        //调用函数,如果函数需要参数,在Java中必须先将参数转化为对应的“Python类型”
        PyObject pyobj = pyFunction.__call__(new PyInteger(a), new PyInteger(b));
        System.out.println("the anwser is: " + pyobj);

        // 报错unindent does not match any outer indentation level
        // python对缩进具有严格的要求
        // 1、代码前后缩进量不一致
        // 2、代码前后缩进符号不一致
        // 3、tab与space混用
        // 报错SyntaxError: Non-ASCII character in file
        // 1, 出现的原因: python的默认编码文件是用ASCII码,没有支持UTF-8,而你的python文件中使用了中文等非英语字符。
        // 2,因此,解决的方法,在文件的开头输入如下:
        // # -*- coding: UTF-8 -*-    或者  #coding=utf-8
    }
    /**
     * Jython 执行python文件,引用自定义+系统python模块
     */
    @Test
    public void test4() {
        /*************python***************
             #coding=utf-8
             import fun
             import datetime

             def add(a, b):
                 print("方法调用时间:" + str(datetime.datetime.now()))
                 fun.greeting(str(a))
                 fun.greeting(str(b))
                 return a + b

             fun.greeting("wsl")
             print("当前时间:" +str(datetime.datetime.now()))
         **********************************/
        //System.setProperty("python.home", "D:\\tools\\python");
        PythonInterpreter interpreter = new PythonInterpreter();
        // 引用自定义python模块
        PySystemState sys = Py.getSystemState();
        sys.path.add("D:\\py_test");//import 模块的文件目录
        interpreter.exec("import fun");//添加模块引用 es: import fun
        // 加载python脚本
        interpreter.execfile("D:\\py_test\\add.py");
        // 第一个参数为期望获得的函数(变量)的名字,第二个参数为期望返回的对象类型
        PyFunction pyFunction = interpreter.get("add", PyFunction.class);
        int a = 5, b = 10;
        //调用函数,如果函数需要参数,在Java中必须先将参数转化为对应的“Python类型”
        PyObject pyobj = pyFunction.__call__(new PyInteger(a), new PyInteger(b));
        System.out.println("the anwser is: " + pyobj);

        // 报错unindent does not match any outer indentation level
        // python对缩进具有严格的要求
        // 1、代码前后缩进量不一致
        // 2、代码前后缩进符号不一致
        // 3、tab与space混用
        // 报错SyntaxError: Non-ASCII character in file
        // 1, 出现的原因: python的默认编码文件是用ASCII码,没有支持UTF-8,而你的python文件中使用了中文等非英语字符。
        // 2,因此,解决的方法,在文件的开头输入如下:
        // # -*- coding: UTF-8 -*-    或者  #coding=utf-8
    }

    /**
     * 通过Runtime.getRuntime()开启进程来执行脚本文件
     */
    @Test
    public void test5() {
        // python安装目录  cmd  pip install requests
        /*************python***************
             #coding=utf-8
             import urllib.request
             response = urllib.request.urlopen('http://www.baidu.com')
             html =str(response.read(),'utf-8')
             print(html)
         **********************************/
        // args[0]表示要执行的是python 脚本 ,args[1] 脚本文件的全路径
        String[] arguments = new String[]{"D:\\tools\\python\\python.exe", "D:\\py_test\\request.py"};
        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();
            // 在此需要注意的一点,java代码中的process.waitFor()返回值为0表示我们调用python脚本成功,
            // 返回值为1表示调用python脚本失败,这和我们通常意义上见到的0与1定义正好相反。
            int re = process.waitFor();
            System.out.println(re);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过Runtime.getRuntime()开启进程来执行脚本文件,传参
     */
    @Test
    public void test6() {
        /*************python***************
             #coding=utf-8
             def greeting(name):
             print("你好, " + name)
             greeting(sys.argv[1]) #sys.argv[0] 存储的是py文件自身的路径,故接受参数从sys.argv[1]开始
             greeting(sys.argv[2])
         **********************************/

        try {
            // 因此在python代码中我们需要通过sys.argv的方式来拿到java代码中传递过来的参数。
            int a = 18;
            int b = 23;
            //String[] args = new String[] { "D:\\tools\\python\\python.exe", "D:\\py_test\\test.py", String.valueOf(a), String.valueOf(b) };
            // args[0]表示要执行的是python 脚本 ,args[1] 脚本文件的全路径
            String[] args = new String[]{"D:\\tools\\python\\python.exe", "D:\\py_test\\test.py", String.valueOf(a), String.valueOf(b)};
            // sys.argv[0] 存储的是py文件自身的路径,故接受参数从sys.argv[1]开始
            Process pr = Runtime.getRuntime().exec(args);
            BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream(), "GBK"));// 解决乱码
            String line;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
            in.close();
            // 在此需要注意的一点,java代码中的process.waitFor()返回值为0表示我们调用python脚本成功,
            // 返回值为1表示调用python脚本失败,这和我们通常意义上见到的0与1定义正好相反。
            int waitFor = pr.waitFor();
            System.out.println(waitFor);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 通过Runtime.getRuntime()开启进程来执行脚本文件,json传参
     */
    @Test
    public void test7() {
        // python安装目录  cmd  pip install demjson
        // https://www.runoob.com/python/python-json.html
        /*************python***************
             #coding=utf-8
             import sys
             import demjson

             str=sys.argv[1] #str得到的key没有双引号
             print(str)
             #直接用json.loads(str)报错
             data=demjson.decode(str)
             print(data)
         **********************************/
        try {
            // 因此在python代码中我们需要通过sys.argv的方式来拿到java代码中传递过来的参数。
            Map<String, String> map = new HashMap<>();
            map.put("name", "wsl");
            map.put("age", "25");
            String arg = JSON.toJSONString(map);
            arg = "'" + arg + "'";//json 参数要加单引号,没有单引号解析失败
            // args[0]表示要执行的是python 脚本 ,args[1] 脚本文件的全路径
            String[] args = new String[]{"D:\\tools\\python\\python.exe", "D:\\py_test\\request.py", arg};
            // sys.argv[0] 存储的是py文件自身的路径,故接受参数从sys.argv[1]开始
            Process pr = Runtime.getRuntime().exec(args);
            BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream(), "GBK"));// 解决乱码
            String line;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
            in.close();
            // 在此需要注意的一点,java代码中的process.waitFor()返回值为0表示我们调用python脚本成功,
            // 返回值为1表示调用python脚本失败,这和我们通常意义上见到的0与1定义正好相反。
            int waitFor = pr.waitFor();
            System.out.println(waitFor);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 通过Runtime.getRuntime()开启进程来执行脚本文件,argparse接收参数
     */
    @Test
    public void test8() {
        // python安装目录  cmd  pip install demjson
        // https://www.runoob.com/python/python-json.html
        /*************python***************
             # coding=utf-8
             import argparse
             import sys
             import demjson

             if __name__ == '__main__':
                 parser = argparse.ArgumentParser()
                 parser.add_argument("--input_path", type=str, help="image input path")
                 parser.add_argument("--output_image", type=str, help="result image output path")
                 parser.add_argument("--output_json", type=str, help="result json output path")
                 args = parser.parse_args()
                 print(args.__str__())
         **********************************/
        try {
            String[] args = new String[]{"D:\\tools\\python\\python.exe", "D:\\py_test\\request.py"
                    ,"--input_path=/home/data/rB8BlV6FPcSAVLTmAAGQQ-II1tI341.jpg"
                    ,"--output_image=/home/img/341.jpg"
                    ,"--output_json=/home/json/341.txt"};
            // args[0]表示要执行的是python 脚本 ,args[1] 脚本文件的全路径
            //String[] args = new String[]{"D:\\tools\\python\\python.exe", "D:\\py_test\\request.py", envp};
            // sys.argv[0] 存储的是py文件自身的路径,故接受参数从sys.argv[1]开始
            Process pr = Runtime.getRuntime().exec(args);
            BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream(), "GBK"));// 解决乱码
            String line;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
            in.close();
            // 在此需要注意的一点,java代码中的process.waitFor()返回值为0表示我们调用python脚本成功,
            // 返回值为1表示调用python脚本失败,这和我们通常意义上见到的0与1定义正好相反。
            int waitFor = pr.waitFor();
            System.out.println(waitFor);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值