——引言
直接进主题,本项目在“基于知识图谱的医药问答系统实战”的基础上,结合Untiy做的前端,实现了Windows系统下的可视化医药智能问询系统。
U3D端的结果展示如下,
Unity+Python医药问询系统前端展示
这其中遇到了一些困难,包括Python环境的配置、Python中安装包版本的适配,Unity与Python程序的通信,中途遇到的各种程序实现困难和bug等等,下面做一个学习过程的梳理,记录一下主要遇到的困难。
一、背景介绍
- 关于知识图谱
网上的介绍很多,根据我的理解,知识图谱是运用图数据库(主流用Neo4j)来建立和展示实体、属性及其关系的一个领域知识网络拓扑图。(大家以专业解释为准)建立好这个图数据库之后,可以通过程序操作图数据库,开发应用程序,如专家系统等。 - Unity3D开发前端
为什么用U3D,原因是我本行是做U3D开发的,其他合适的前端开发方式都可以。
二、开发过程遇到的主要困难及解决方案
3. Python环境配置
因为项目是2020的,用的Python3.6,其他安装包的下载安装隔得时间长了,不完全记得,可以参考“中文医学知识图谱CMeKG项目环境配置的摸索”
先把已经Python程序调试跑通。
-
Unity中用Process API调用Python程序,遇到中文无法正确编码解码的问题
由于需要从Unity传输用户的问题(中文)给Python程序,于是用了Process中的参数传递方法,但发现Untiy发给Python的中文经过参数传回打印,发现无法正确解码为对应的中文内容。
为了解决这个问题,把Unicode,utf8,gbk…的原理都看了,也尝试了各种编码解码的方式,都没能解决,如果有大神能提供方案,万分感谢~
最后,选择了用MySQL,通过Unity将中文问题写入数据库,Python程序读取数据库的方式来解决中文字符通信的问题。 -
Unity写数据,Python读数据都不难实现,也各自通过测试。而后Python根据问题找到答案后,同样写入MySQL数据库,Unity再去对应读取中文答案,展示出来。但当程序完整去执行的时候,Unity调用Python会完全卡主,不知道Python有没有正常运行,因为这里是用Process调用执行Python,看不到Python的运行情况,所以又用了记录日志的方式去测试Python程序究竟卡在哪里了。
打印Python日志,我用了很简单的一个“import logging”的方式,短短一行代码logging.basicConfig(filename=‘路径/文件名称.log’, level=logging.DEBUG, format=‘%(asctime)s - %(levelname)s - %(message)s’, datefmt=‘%Y-%m-%d %H:%M:%S’) 就解决了。
打印日志,发现Python程序卡在
self.disease_wds= [i.strip() for i in open(self.disease_path,encoding=“utf-8”) if i.strip()]
为什么会卡在这儿呢?是因为循环吗?用for循环测试了一下,Unity里面能跑的通for循环这段代码,这个问题足足花了一两天时间,最后被ChatGPT解决了,如下截图给的灵感:
问题居然出在此语句中用到的path,Python程序中文件路径用的/ ,Windows中要用\ 。其实这个问题我挺纳闷的,比如上面的logging路径,我就用的/,没有问题。不管怎么样,这里换成“\” (两个反斜杠,发布后变成一个反斜杠了),程序就跑通了。
对了,上面Phyton卡住,我用了日志,只测出来卡在了哪一句,但我并不确定Python程序究竟是卡住了,还是退出了,最后确定是退出了,如何知道的呢?
在Unity中,通过以下代码
// Handle Exited event and display process information.
private void myProcess_Exited(object sender, System.EventArgs e)
{
print(
$“Exit time : {pythonProcess.ExitTime}\n” +
$“Exit code : {pythonProcess.ExitCode}\n” +
$“Elapsed time : {Math.Round((pythonProcess.ExitTime - pythonProcess.StartTime).TotalMilliseconds)}”);
eventHandled.TrySetResult(true);
}
在Process 调用执行python前的配置中,加一句pythonProcess.Exited += new EventHandler(myProcess_Exited);
这样就可以知道python的运行情况,当时报的exit code:1 ,经过查询说发生这个一般是由于循环导致的退出,印证了之前打印日志显现的问题。
三、总结
整个项目的制作过程遇到的细节问题肯定不止这些,记下来的是我印象深刻的部分。“车到山前必有路”,要相信,遇到困难,想办法去解决,总会有出路的。