Jython-Java中执行python函数,并获取返回值

 

Java中执行python函数的方式有多种,如果需要得到返回值,这里推荐一种方式,可以使用jython嵌入到代码里运行。

依赖和代码都在下面了,需要自取,都是多次调试后的最终版,绝对能跑。

 <!-- https://mvnrepository.com/artifact/org.python/jython-standalone -->
        <dependency>
            <groupId>org.python</groupId>
            <artifactId>jython-standalone</artifactId>
            <version>2.7.1</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
package com.example.demo;


import lombok.extern.slf4j.Slf4j;
import org.python.core.Py;
import org.python.core.PyObject;
import org.python.core.PyString;
import org.python.util.PythonInterpreter;

import java.util.*;

/**
 * @author lilong
 * @date 2020/12/01
 * @desc
 */
@Slf4j
public class PythonUtil {

    /**
     * 设置一个关键key,用于从python中获取结果
     */
    private static String resultKey = "result";

    /**
     * 系统变量
     */
    static {
        Properties props = new Properties();
        props.put("python.home", "path to the Lib folder");
        props.put("python.console.encoding", "UTF-8");
        props.put("python.security.respectJavaAccessibility", "false");
        props.put("python.import.site", "false");
        Properties preProps = System.getProperties();
        PythonInterpreter.initialize(preProps, props, new String[0]);
    }

    /**
     * 执行python脚本
     * @param express 脚本,需要注意换行格式正确
     * @param map 入参变量集合,key为变量名,value为变量值
     * @return
     */
    public static String doExpress(String express, Map<String, Object> map) {
        try (PythonInterpreter pythonInterpreter = new PythonInterpreter()) {
            map.forEach((key, value) -> {
                PyObject pyValue;
                if (value instanceof String) {
                    //中文乱码解决
                    pyValue = Py.newStringUTF8(value.toString());
                } else if (value instanceof Float || value instanceof Double) {
                    //python和java浮点精度不一致问题,都转为double
                    pyValue = Py.newFloat(Double.parseDouble(value.toString()));
                } else if (value instanceof Integer) {
                    pyValue = Py.newInteger((int) value);
                } else {
                    pyValue = Py.java2py(value);
                }
                pythonInterpreter.set(key, pyValue);
            });
            express = express.replace("return", resultKey + "=");
            
            log.info("input map:{},express:{}", map, express);
            
            PyString pyString = Py.newStringUTF8(express);
            pythonInterpreter.exec(pyString);
            return pythonInterpreter.get(resultKey).toString();
        } catch (Exception e) {
            log.error("执行python脚本出错: {} input: \n{} \nexpress: \n{}", e.toString(), map, express);
            throw new RuntimeException("执行python脚本出错" + e.toString());
        }
    }

    public static void main(String[] args) {
        Map<String, Object> input = new HashMap<>(4);

        String express = 
                "if args in [1.0,'1','挑葱夫']:\n" +
                "    return 1\n" +
                "else:\n" +
                "    return 0";

        input.put("args", "1");
        log.info(doExpress(express, input));
        input.put("args", "挑葱夫");
        log.info(doExpress(express, input));
        input.put("args", 1.0);
        log.info(doExpress(express, input));
    }
}

有问题留言沟通,谢谢。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值