在Java代码中使用Python

使用技术

要在Java代码中调用python代码方法,我们可以使用Java的ProcessBuilder类来创建一个新进程,将Python解释器作为该进程的命令并传递要执行的Python脚本作为参数。
以下是一些基本的代码示例:

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

public class PythonCaller {
    public static void main(String[] args) {
        try {
            // 创建ProcessBuilder对象
            ProcessBuilder pb = new ProcessBuilder("python", "hello.py");
            // 启动进程
            Process process = pb.start();
            // 获取进程的输出流
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            // 等待进程完成
            int exitCode = process.waitFor();
            System.out.println("Exited with error code " + exitCode);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在上面的示例中,我们将ProcessBuilder对象的参数设置为python和hello.py,其中hello.py是我们要执行的Python脚本文件。该进程将启动Python解释器并执行该脚本。我们使用缓冲读取器来获取该进程的输出流,并在控制台上打印该进程的输出。最后,我们等待进程完成并检查它的退出代码。

那么我们应该怎么调用Python中的函数呢?

调用Python中的函数

要在Java代码中调用Python脚本中的特定函数,您需要使用ProcessBuilder对象的参数来传递要执行的Python脚本以及要执行的函数,并将这些信息传递给Python脚本作为参数。

  1. 在Python脚本hello.py中定义一个简单的hello()函数:
def hello():
    print("Hello from Python!")
  1. 在Java代码中使用ProcessBuilder对象的参数来执行hello.py脚本并传递函数名称作为参数
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class PythonCaller {
    public static void main(String[] args) {
        try {
            // 创建ProcessBuilder对象
            ProcessBuilder pb = new ProcessBuilder("python", "hello.py", "hello");
            // 启动进程
            Process process = pb.start();
            // 获取进程的输出流
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            // 等待进程完成
            int exitCode = process.waitFor();
            System.out.println("Exited with error code " + exitCode);
        } catch (Exception  e) {
            e.printStackTrace();
        }
    }
}

在上述代码中,我们将ProcessBuilder对象的参数设置为python,hello.py和hello字符串。此命令将启动Python解释器并执行hello.py脚本。Python脚本将检查传递的函数名称参数是否匹配脚本中定义的函数名称,并执行hello()函数。在该进程的输出流中,我们可以打印由该函数打印的任何内容。

请注意:您需要确保将Python脚本文件的路径正确地指定为ProcessBuilder对象所在的目录。您还需要使用与Python解释器版本相同的Java版本编译Java代码,否则可能会遇到问题。

获取函数执行的结果

要将Python脚本的函数返回值返回给Java代码,您需要使用Java的Process对象中的getInputStream()方法获取进程的输出流。在Python脚本中,您可以使用Python的print()函数将函数的返回值打印到标准输出。然后,您可以在Java代码中使用BufferedReader对象读取输出流,并将其输出到控制台或将其存储到变量中。
Python代码:

def hello():
    return "Hello from Python!"
    
print(hello())

Java代码

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

public class PythonCaller {
    public static void main(String[] args) {
        try {
            // 创建ProcessBuilder对象
            ProcessBuilder pb = new ProcessBuilder("python", "hello.py", "hello");
            // 启动进程
            Process process = pb.start();
            // 获取进程的输出流
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            StringBuilder result = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }
            // 等待进程完成
            int exitCode = process.waitFor();
            System.out.println("Exited with error code " + exitCode);
            // 打印结果
            System.out.println("Python函数的结果是:" + result);
        } catch (Exception  e) {
            e.printStackTrace();
        }
    }
}

在上述代码中,我们在hello()函数中添加了一个返回语句,以便您可以返回Python函数的返回值。然后,我们使用print()函数将Python函数的返回值打印到标准输出。在Java代码中,我们使用BufferedReader对象读取输出流,将它们存储到一个StringBuilder对象中,然后将其打印到控制台。请注意,由于Python脚本的输出以换行符结尾,我们在读取输出流时需要添加一个循环来读取所有行,并将它们附加到StringBuilder对象中。最后,我们在控制台上打印Python函数的结果。

那么如果要在Java代码中输入Python函数中的参数呢?

Java代码中输入Python函数中的参数

如果Python函数带有参数,您可以在Java代码中将这些参数作为命令的一部分传递给Python脚本。Python脚本可以读取这些参数,并将它们传递给Python函数。

Python代码:

import sys

def hello(name):
    print("Hello, " + name + "!")

我们使用Python模块sys来获取由Java代码传递的参数,将其传递给Python函数,然后使用print()函数将结果打印到标准输出。

在Java代码中使用ProcessBuilder对象的参数来执行hello.py脚本并传递参数到函数中。
Java代码:

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

public class PythonCaller {
    public static void main(String[] args) {
        try {
            // 创建ProcessBuilder对象
            ProcessBuilder pb = new ProcessBuilder("python", "hello.py", "World");
            // 启动进程
            Process process = pb.start();
            // 获取进程的输出流
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            // 等待进程完成
            int exitCode = process.waitFor();
            System.out.println("Exited with error code " + exitCode);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在上述代码中,我们将ProcessBuilder对象的命令参数设置为python,hello.py和World字符串,可以将任何其他字符串传递作为参数,它将被传递到Python函数中作为函数的参数,Python脚本将读取这些参数,并将它们传递给hello()函数。

Python函数输入多个参数

以下用Python函数计算两个数的和
Python文件

import sys

def add(num1, num2):
    return num1 + num2

传递两个参数和和上面传递一个参数一样, 在Java代码中使用ProcessBuilder对象的参数来执行hello.py脚本并向函数中传递两个参数

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

public class PythonCaller {
    public static void main(String[] args) {
        try {
            // 创建ProcessBuilder对象
            ProcessBuilder pb = new ProcessBuilder("python", "hello.py", "2", "3");
            // 启动进程
            Process process = pb.start();
            // 获取进程的输出流
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            // 等待进程完成
            int exitCode = process.waitFor();
            System.out.println("Exited with error code " + exitCode);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在上述代码中,我们将ProcessBuilder对象的命令参数设置为python,hello.py,2和3字符串,其中2和3是要传递给add()函数的参数。Python脚本将读取这些参数,并使用add()函数来计算它们的和。结果将使用print()函数在标准输出中打印。

如果我们想在Java代码中获取函数执行的结果呢?

在Java代码中获取函数执行结果

要将Python函数add()计算的结果返回给Java代码,可以使用Java的Process对象中的 getInputStream() 方法获取进程的输出流,Python脚本可以使用 print() 函数将函数的返回值打印到标准输出中。在Java代码中,您可以使用 BufferedReader 对象读取输出流,将值存储到变量中,最后将它打印到控制台或者将其存储到对应的变量中。

Python代码:

import sys

def add(num1, num2):
    return num1 + num2
    
print(add(int(sys.argv[1]), int(sys.argv[2])))

在上述代码中,我们定义了一个 add() 函数,该函数接收两个参数 num1 和 num2,将它们相加并返回结果。我们使用 sys.argv[] 从 Python 脚本中读取传递给函数的参数,并使用 print() 函数将结果打印到标准输出中。

Java 代码:

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

public class PythonCallerExample {

    public static void main(String[] args) {
        try {
            ProcessBuilder processBuilder = new ProcessBuilder("python", "hello.py", "2", "3");
            Process process = processBuilder.start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            StringBuilder stringBuilder = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
            }
            int exitCode = process.waitFor();
            System.out.println("Exited with error code " + exitCode);
            System.out.println("Result: " + stringBuilder.toString());
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在上述代码中,我们使用 ProcessBuilder 启动 Python 进程,将要执行的 Python 脚本以及参数传递给进程。我们使用 BufferedReader 读取进程的输出流,并使用 StringBuilder 存储传递给 Python 函数后计算出的和。最后,我们打印结果和状态码。

请注意:您需要确保将 Python 脚本文件的路径正确指定为 ProcessBuilder 对象所在的目录,而且传递的参数数量和顺序需要正确。

当然除了使用sys.argv[]方法外,我们还可以使用以下是两个常用的方法:

  1. 使用 argparse 模块
    argparse 是 Python 内置的一个命令行解析模块,可以用来解析命令行参数。您可以使用 argparse 模块来定义需要传递的参数,然后在 Python 脚本中使用这些命令行参数。

Python 代码示例:

import argparse

def add(num1, num2):
    return num1 + num2

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('num1', type=int)
    parser.add_argument('num2', type=int)
    args = parser.parse_args()
    print(add(args.num1, args.num2))

在上述代码示例中,我们使用 argparse 模块来定义了需要传递的两个参数 num1 和 num2。通过 parser.add_argument() 方法,我们可以定义传递的参数名称、类型和参数描述等属性。在脚本的主函数中,我们使用 parser.parse_args() 方法解析命令行参数,并将其传递给 add() 函数。在最后一行,使用 print() 将计算结果打印到标准输出。

Java代码示例:

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

public class PythonCallerExample {
    public static void main(String[] args) {
        try {
            ProcessBuilder processBuilder = new ProcessBuilder("python", "hello.py", "2", "3");
            Process process = processBuilder.start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            StringBuilder stringBuilder = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
            }
            int exitCode = process.waitFor();
            System.out.println("Exited with error code " + exitCode);
            System.out.println("Result: " + stringBuilder.toString());
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在 Java 代码中,我们使用与之前示例相同的 ProcessBuilder, 并使用 argparse 的方式定义两个参数。因为该示例使用相同的命令行参数来调用 Python 脚本,所以不需要对 Java 代码进行任何修改,但如果参数有所不同,则需要相应地更改 ProcessBuilder 中的参数。
2. 使用 subprocess 模块
subprocess 模块是 Python 内置的一个子进程管理模块。您可以使用这个模块来启动一个 Python 子进程,在子进程中执行 Python 脚本,并传递参数到 Python 子进程中。

Python 代码示例:

import sys

def add(num1, num2):
    return num1 + num2

if __name__ == '__main__':
    num1 = int(sys.stdin.readline().strip())
    num2 = int(sys.stdin.readline().strip())
    print(add(num1, num2))

在上述代码示例中,我们使用 sys.stdin.readline() 来读取从父进程传递的两个参数,并将其传递给 add() 函数。在最后一行,使用 print() 将计算结果打印到标准输出。

Java代码示例:

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

public class PythonCallerExample {

    public static void main(String[] args) {
        try {
            ProcessBuilder processBuilder = new ProcessBuilder("python");
            Process process = processBuilder.start();
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            process.getOutputStream().write(in.readLine().getBytes("UTF-8"));
            process.getOutputStream().write('\n');
            process.getOutputStream().write(in.readLine().getBytes("UTF-8"));
            process.getOutputStream().write('\n');
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            int exitCode = process.waitFor();
            System.out.println("Exited with error code " + exitCode);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

以上代码创建 BufferedReader 对象并将其连接到 Python 进程的输入流和输出流:in 和reader
一个用于读取用户输入,另一个用于读取 Python 进程的输出。
以下代码用于发送用户输入到 Python 进程并读取其输出:

process.getOutputStream().write(in.readLine().getBytes("UTF-8"));
process.getOutputStream().write('\n');
process.getOutputStream().write(in.readLine().getBytes("UTF-8"));
process.getOutputStream().write('\n');
while ((line = reader.readLine()) != null) {
    System.out.println(line);
}

在这里,我们使用 process.getOutputStream() 将用户输入发送到 Python 进程,并使用 reader 读取 Python 进程的输出。该程序将循环运行直到 Python 进程输出的内容返回 null。在每次循环迭代中,我们将 Python 进程输出的行打印到控制台上。

好了, 在Java代码中操作Python就介绍到这儿, 其他内容欢迎大家评论讨论

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java调用Python代码有多种方法,其一种是使用Jython。Jython是一个Java平台上的Python解释器,它允许在Java程序嵌入Python代码,并且可以在Java代码直接调用Python模块和函数。 以下是使用Jython在Java调用Python代码的基本步骤: 1. 下载并安装Jython 你可以从Jython官方网站下载Jython安装包,并按照安装向导进行安装。 2. 创建Python脚本 编写一个Python脚本,例如hello.py: ``` def say_hello(name): print("Hello, " + name + "!") ``` 3. 在Java代码加载并调用Python模块 在Java代码使用Jython的PythonInterpreter类加载并调用Python模块和函数,例如: ``` import org.python.util.PythonInterpreter; public class Main { public static void main(String[] args) { PythonInterpreter interpreter = new PythonInterpreter(); interpreter.execfile("hello.py"); interpreter.get("say_hello").__call__("John"); } } ``` 在上面的代码,我们首先创建了一个PythonInterpreter对象,然后使用它的execfile方法加载Python脚本文件。接着,我们使用interpreter.get方法获取Python模块的say_hello函数,并使用__call__方法调用该函数,并传递一个参数。 当你运行Java程序时,你应该能够在控制台上看到输出:Hello, John! 需要注意的是,Jython并不是Python的完全实现,它只支持Python 2.7的语法和一些标准库。如果你的Python代码使用了不受支持的语法或库,那么你需要考虑其他的方法来在Java调用Python代码

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值