20230711 记录python和Java混合编程的一些问题(Eclipse)

文章详细阐述了在Java中调用Python脚本时的关键点,包括使用-u参数实现无缓冲输出,选择正确的编码(如GB2312)避免乱码,澄清Jython版本误解,以及处理Python脚本错误和警告。此外,还提醒读者注意Python环境变量的配置,确保Java调用的是正确路径下的Python解释器,并强调了全局变量在多文件交互中的重要性,以解决NameError问题。
摘要由CSDN通过智能技术生成

关于常用的Java调用python的方法:

Process proc;
try {
    proc = Runtime.getRuntime().exec(pythonpath + " -u " + pyfilepath);
    BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream(), "gb2312"));
    String line = null;
    while ((line = in.readLine()) != null) {
        System.out.println(line);
    }
    in.close();
    proc.waitFor();
} catch (IOException e) {
    e.printStackTrace();
} catch (InterruptedException e) {
    e.printStackTrace();
}

这里有若干地方需要注意,在这里进行说明:

(1)"-u"命令

proc = Runtime.getRuntime().exec(pythonpath + " -u " + pyfilepath);

“-u”命令代表一种实时的操作命令,如果对Java调用python程序有实时要求时,这是必需的;

(2)“GB2312”编码格式

BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream(), "gb2312"));
String line = null;
while ((line = in.readLine()) != null) {
    System.out.println(line);
}

不论是Java还是python,utf-8、gb2312或者gbk格式不统一,都会造成乱码,例如生僻汉字、问号种种;

在这个问题上,首先需要明确python的print输出到控制台的格式是什么,print默认的输出格式为GB2312,

在被Java用缓冲流读取时,其格式发生了改变,因此需要在缓冲流创建时将读取的内容直接转为GB2312。

根据网络上的检索显示,GB2312并非是唯一答案,而取决于每台电脑及使用者的风格,因此需要根据自己的实际情况进行改变。

△需要注意的是,根据调试结果,将GB2312设置在while循环中,即读取line时进行转换是没有效果的,必须在缓冲流创建时就将其转换;

(3)关于jython包

网络上有部分答案误导了jython包的版本,在其注释内往往标注为jython包为2.x或3.x版本,jython包并没有3.x版本,到现在为止最高版本为2.7.x,应该与python包进行区分

(4)报错问题

用Java调用python的调试过程中,一旦py文件出现了问题,往往不会反映在控制台上,Java将直接跳过py程序;

此外,务必要区分pycharm环境运行py与Java调用python的过程,一是pycharm中下载的包与Java调用py文件时的包并不一致,

如前所述:

proc = Runtime.getRuntime().exec(pythonpath + " -u " + pyfilepath);

这里给出pythonpath与pyfilepath的示例格式(绝对路径):

E:\\python3.11\\Python311\\python.exe

F:\\EquationModelResult\\Python\\SCE_OP.py

这里的python.exe的包应来自于Python311以下,而非Pycharm已经安装的包,需通过pip命令下载。

二是pycharm是一个IDE,可否通过Java直接调用并没有经过尝试;

三是如果代码涉及到数学公式,例如fsolve这类数学运算函数,建议是将pycharm环境中出现的,不会对主程序的运行或计算结果的对错产生灾难性影响的例如runtime warning忽略,本例中忽略方法的代码如下:

import warnings
warnings.filterwarnings("ignore")

根据调试过程,如果这些warning存在,Java在接收到这些warning后将停止运行;

总而言之,Java在调用python时直接跳过py文件较为麻烦,一旦py文件存在错误,Java将无法反映这些错误,因此遇到这种情况最好的办法是回到py文件中。

其次是注意pycharm的包和实际应用的python解译工具的包是不是一致的。

最后关于py文件有一个值得说明的地方是,

我们经常会面临一个py文件调用另一个py文件的情况,这种时候可能出现变量名未定义,即Name Error类似的报错信息。

这里给出的解释是,另一个py文件中的变量通常是局部变量,一旦主py文件调用完毕之后就将销毁,下一次调用时就无法找到这个变量。

解决该问题的方法是,涉及到哪个变量就将这个变量如下表示

global x

其中x代表任何一个你需要考虑的变量,这句话需要定义在变量赋值之前

PS:这个变量不局限于自己定义的变量,缩写的包名如numpy-np,或者matplotlib-mp都可能需要在py文件的开头位置定义全局变量;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值