IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> Java 调用 python 的接口 -> 正文阅读

[开发测试]Java 调用 python 的接口

? ? 不管什么技术,不管什么问题,只要努力就能解决。

? ? 最近在做项目的时候,需要java 调用 python 接口,在网上找了一些方法,但是总碰到一些问题,索性将网上的方法和自己的理解总结一下,希望对各位博友有所帮助,也请各位大神不吝赐教。

一:创建环境 Python 环境


import org.python.core.PySystemState;
import org.python.util.PythonInterpreter;
/**
 * Jython环境,生存python解释器
 * @author webim
 *
 */
public final class JythonEnvironment
{
    private static JythonEnvironment INSTANCE = new JythonEnvironment();

    /**
     * 私有构造方法
     */
    private JythonEnvironment()
    {
    }

    /**
     * 获取单例
     * @return JythonEnvironment
     */
    public static JythonEnvironment getInstance()
    {
        return INSTANCE;
    }

    /**
     * 获取python系统状态,可根据需要指定classloader/sys.stdin/sys.stdout等
     * @return PySystemState
     */
    private PySystemState getPySystemState()
    {
        PySystemState.initialize();
        final PySystemState py = new PySystemState();
        py.setClassLoader(getClass().getClassLoader());
        return py;
    }

    /**
     * 获取python解释器
     * @return PythonInterpreter
     */
    public PythonInterpreter getPythonInterpreter(){
        PythonInterpreter inter = new PythonInterpreter(null, getPySystemState());
//        PythonInterpreter inter = new PythonInterpreter();
        return inter;
    }
    
    
}

二:调用 python 的接口

添加 JPython 依赖

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

上面这个依赖有问题,可用下面依赖避免各种问题。

        <dependency>
            <groupId>org.python</groupId>
            <artifactId>jython-standalone</artifactId>
            <version>2.7.0</version>
        </dependency>
因为 python 和 java是两种不同的语言,因此在项目的 controller 、service 和 mapper 中直接出现 Python 的接口,因此
自己封装  ExecPython   类,
封装python的接口,目的让 python 接口和java程序分隔开。

import org.python.core.PyFunction;
import org.python.core.PyObject;
import org.python.util.PythonInterpreter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.Map;

/*enum的这个用法,可以作为变种的安全单例,值得借鉴哦 ^_^ */
@Service
@Component
public class ExecPython {

    public static final Logger logger = LoggerFactory.getLogger(Exception.class);

    //定义 python 解释器
    private static PythonInterpreter inter;

    public ExecPython() {
        this.inter  = JythonEnvironment.getInstance().getPythonInterpreter();
        this.inter.execfile("C:\\test.py");
    }

    //设置 python 脚本的路径
    public void setPythonPath (String pythonPath){
        this.inter.execfile(pythonPath);
    }



    public void execute(String scriptFile, Map<String,String> properties)
    {
        logger.info("获取解释器");
        try
        {

            PyFunction getNetInfo = (PyFunction) inter.get("getNetInfo", PyFunction.class);
            PyObject netInfo = getNetInfo.__call__();
            System.out.println("anwser = " + netInfo.toString());
        }
        catch (Exception e)
        {
            e.printStackTrace();
            logger.info("Python 脚本文件执行失败");
        }
    }

    //获取 Python 字符串
    public String getString(){
//获取到python 脚本中的接口
        PyFunction func = (PyFunction) inter.get("adder", PyFunction.class);
        PyObject pyobj = func.__call__();
        System.out.println("anwser = " + pyobj.toString());
        return pyobj.toString();
    }
    // 获取当前数组
    public String getArr() {
        PyFunction getArr = (PyFunction) inter.get("getArr", PyFunction.class);
        PyObject pyobjTwo = getArr.__call__();
        pyobjTwo.__len__();
        System.out.println("anwser = " + pyobjTwo.toString()+" len:"+pyobjTwo.__len__());

        //将 PyObject 对象转换成 java  对象
        //Object object = pyobjTwo.__tojava__(List.class);
        //List<String> list = (List<String>) object;

        //将查询到数据转换成一个 JSON 字符串
        String result = pyobjTwo.toString();
        String JsonStr = "{" + result + "}";
        logger.info(JsonStr);
        logger.info("将查询的结果转换成 JSON 字符串:",JsonStr);

        return pyobjTwo.toString();
    }
}
?

三: python 脚本

def adder():? ??
? ?return "{'name':'leilei','age':'18'}"??
? ?
def getArr():
return ['aaa','bbb']


def getNetInfo():
return [{'DNS':'192.168.12.3','ip':'45.23.16.0'},{'DNS2':'192.168.12.2','ip2':'45.23.16.2'}]

问题:

2019-12-09 20:11:17.070 ERROR 4620 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'execPython' defined in file [D:\Lenovo\LenovoWorkspace\code\ip-modify\target\classes\cn\lenovo\ipmodify\service\ExecPython.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [cn.lenovo.ipmodify.service.ExecPython]: Constructor threw exception; nested exception is ImportError: Cannot import site module and its dependencies: No module named site
Determine if the following attributes are correct:
  * sys.path: ['C:\\Users\\31307\\.m2\\repository\\org\\python\\jython\\2.7.0\\Lib', '__classpath__', '__pyclasspath__/']
    This attribute might be including the wrong directories, such as from CPython
  * sys.prefix: C:\Users\31307\.m2\repository\org\python\jython\2.7.0
    This attribute is set by the system property python.home, although it can
    be often automatically determined by the location of the Jython jar file

You can use the -S option or python.import.site=false to not import the site module

	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1320) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1214) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at cn.lenovo.ipmodify.IpmodifyApplication.main(IpmodifyApplication.java:13) [classes/:na]

主要是这句话:


You can use the -S option or python.import.site=false to not import the site module

可以使用-S选项或python.import.site=false不导入站点模块

像是设置 python 解释器的环境变量。

因此在创建解释器时,设置环境变量。

修改??JythonEnvironment 中的? getPythonInterpreter 函数

    public PythonInterpreter getPythonInterpreter(){

        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]);
        PythonInterpreter inter = new PythonInterpreter();
        return inter;
    }

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-04-15 00:30:46  更:2022-04-15 00:32:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 0:33:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码