【Java】使用Java调用Python的四种方法

写在前面

为啥一个好好的岗位是Java开发工程师要去做写python呢?因为产品经理安排的(突然多少有点明白为啥程序员和产品经理会一直开撕)。由于在选择企业的时候没看清企业性质,看了要求以为就是互联网企业,现在看看初为社畜的我还是太天真了。不过既然这几天已经在写python脚本了,那也不能浪费这段时间的经历了,毕竟python的闪光点也不少。于是想一下如何与老本行Java联系起来,就有了这篇博文。


其实调用的方法也不难,具体调用方法有如下四种(如果有其他办法记得在评论区留下呀):

在使用Java调用python之前,需要导入依赖环境。如,在maven项目中,需要导入如下依赖

<dependency>
    <groupId>org.python</groupId>
    <artifactId>jython-standalone</artifactId>
    <!--python版本是2.x还是3.x在这里指定-->
    <version>2.7.0</version>	
</dependency>

一、在java类中直接执行python语句

在Java类中调用python语句的方法如下

import org.python.util.PythonInterpreter
public class JavaRunPython {
    public static void main(String[] args) {
    	//首先调用python的解释器
        PythonInterpreter interpreter = new PythonInterpreter();
        //选择执行的的Python语句
        interpreter.exec("a='hello world'; ");
        interpreter.exec("print a;");
    }
}

这种方法用的不多、也不推荐大家使用。这里为了整个文章内容的完成性,我把这种方法放在这里。(控制台出现“ Failed to install ‘’: java.nio.charset.UnsupportedCharsetException: cp0”的红标时,不是出错了,而是兼容没做好,可以去运行配置中的Arguments中输入

-Dpython.console.encoding=UTF-8

在正常的情况下,Java工程师只需要调用python开发工程师写的脚本就行了,不会再在代码中加入python语句了。因为在Java语言中添加入其他语言,使Java的可读性下降、执行意义也不是很大(为了一两行代码,去导入python包的性价比太低;而且如果行数多了,就应该是集合成脚本并执行脚本了)

二、在java中直接调用python脚本

这种方式是有些Java程序员使用调用。首先将准备好的脚本,如plus.py

a = 1
b = 2
print a + b

则在Java中运行的模式是这样的:

import org.python.util.PythonInterpreter;
public class JavaPythonFile {
    public static void main(String[] args) {
        PythonInterpreter interpreter = new PythonInterpreter();
        //我在这里使用相对路径,注意区分
        interpreter.execfile("./plus.py");
    }
}

三、★★★使用Runtime.getRuntime()执行python脚本文件,推荐使用

为什么推荐使用这种方式来调用python脚本呢?
答:由于这种办法可以让进程与程序交互。可以看到出现的问题,便于解决

如还是调用上面的脚本为例

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class RuntimeFunction {
    public static void main(String[] args) {
        Process proc;
        try {
        	/*
			附加:
			String[] args1=new String[]{"/home/huan/anaconda2/bin/python","/home/huan/myfile/pythonfile/helloword.py"};
            Process pr=Runtime.getRuntime().exec(args1);
			String数组里的那一行很重要
			首先一定要设置好你所使用的python的位置,切记不要直接使用python,因为系统会默认使用自带的python,所以一定要设置好你所使用的python的位置,否则可能会出现意想不到的问题(比如说我使用的是anaconda中的python,而ubuntu系统会默认调用自带的python,而我自带的python中并没有numpy库,所以会造成相应的代码不会执行的问题,所以设置好python的位置是很重要的)。还有就是要设置好py文件的位置,使用绝对路径。在这里插入代码片

       还有就是可以看出,此方法可以满足我们python代码中调用第三方库的情况,简单实用。
			*/
            proc = Runtime.getRuntime().exec("python ./plus.py");
            BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            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();
        } 
    }
}

对以上代码的解释
首先,为什么要创建Process proc。我们可以去看官方文档:

The ProcessBuilder.start() and Runtime.exec methods create a native process and return an instance of a subclass of Process that can be used to control the process and obtain information about it. The class Process provides methods for performing input from the process, performing output to the process, waiting for the process to complete, checking the exit status of the process, and destroying (killing) the process.

这段文字的意思是: ProcessBuilder.start()和Runtime.exec两个方法会生成一个本地的进程,然后返回一个Processs子类的实例。通过这个实例可以控制进程以及获得关于进程的信息。这个Process类为进程提供可用于执行来自的输入的方法,然后执行输出到这个进程中,等待完成后,检查进程退出时的状态,然后停止这个进程。——换句话说,这个实例就是监视整个进程的。

通过Process的getInputStream(),getOutputStream()和getErrorStream()方法可以得到输入输出流,然后通过InputStream可以得到程序对控制台的输出信息,通过OutputStream可以给程序输入指令,这样就达到了程序的交换功能。

四、调用python脚本中的函数

改造一下python脚本,注意严格的缩进。

def add(a,b):
	a = 1
	b = 2
	print a + b
	return a+b

调用的代码

import org.python.core.PyFunction;
import org.python.core.PyInteger;
import org.python.core.PyObject;
import org.python.util.PythonInterpreter;
public class Function {
    public static void main(String[] args) {
        PythonInterpreter interpreter = new PythonInterpreter();
        interpreter.execfile("./plus.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);
    }

}

参考文献:
java调用python的几种用法(看这篇就够了)
在Java中调用Python
java调用python代码

Java使用`Runtime`调用Python文件并传入参数可以通过执行命令行的方式来实现。以下是一个示例: ```java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { public static void main(String[] args) { try { // 构建命令行命令 String pythonScriptPath = "/path/to/script.py"; String[] cmd = new String[3]; cmd[0] = "python"; // Python解释器的路径,如果已在环境变量中,可以直接使用"python" cmd[1] = pythonScriptPath; cmd[2] = "argument1"; // 传递给Python脚本的参数 // 创建ProcessBuilder对象 ProcessBuilder pb = new ProcessBuilder(cmd); // 启动进程并等待其完成 Process process = pb.start(); int exitCode = process.waitFor(); // 读取Python脚本的输出 BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } if (exitCode == 0) { System.out.println("Python脚本执行成功"); } else { System.out.println("Python脚本执行失败"); } } catch (IOException | InterruptedException e) { e.printStackTrace(); } } } ``` 上述示例中,通过构建命令行命令,在`cmd`数组中定义了要执行的Python脚本路径和传递给脚本的参数。然后通过`ProcessBuilder`启动进程,执行Python脚本。最后可以通过读取进程的输出流来获取Python脚本的输出。 请将示例中的`/path/to/script.py`替换为您实际的Python脚本路径,并根据需要修改传递给脚本的参数。 希望能帮到您!如果有任何疑问,请随时提问。
评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_之桐_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值