当前位置:首页 > Python > 正文

Java调用Python脚本传参方法详解 - 两种实现方式

Java调用Python脚本传参方法详解

在实际开发中,有时需要在Java程序中调用Python脚本并传递参数。本文将介绍两种常用方法:Runtime.getRuntime().exec()ProcessBuilder

方法一:使用Runtime.getRuntime().exec()

这是Java调用外部程序最传统的方法。

Java代码示例:

public class RuntimeExample {
    public static void main(String[] args) {
        try {
            // 定义Python解释器路径、脚本路径和参数
            String pythonPath = "python";
            String scriptPath = "src/main/python/calculate.py";
            String param1 = "10";
            String param2 = "20";
            
            // 构建命令数组
            String[] cmd = {pythonPath, scriptPath, param1, param2};
            
            // 执行Python脚本
            Process process = Runtime.getRuntime().exec(cmd);
            
            // 读取输出流
            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("Python脚本执行结束,退出码: " + exitCode);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Python脚本示例 (calculate.py):

import sys

def main():
    # 获取传递的参数
    if len(sys.argv) < 3:
        print("请提供两个数字作为参数")
        return
    
    try:
        num1 = int(sys.argv[1])
        num2 = int(sys.argv[2])
        result = num1 + num2
        print(f"{num1} + {num2} = {result}")
    except ValueError:
        print("参数必须是整数")

if __name__ == "__main__":
    main()

方法二:使用ProcessBuilder

ProcessBuilder提供了更灵活的控制,推荐使用。

Java代码示例:

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

public class ProcessBuilderExample {
    public static void main(String[] args) {
        try {
            // 设置Python解释器和脚本路径
            String pythonPath = "python";
            String scriptPath = "src/main/python/analyze.py";
            
            // 创建ProcessBuilder并设置命令
            ProcessBuilder pb = new ProcessBuilder(
                pythonPath, 
                scriptPath,
                "--input", "data.csv",
                "--output", "report.pdf",
                "--verbose"
            );
            
            // 合并错误流到标准输出
            pb.redirectErrorStream(true);
            
            // 启动进程
            Process process = pb.start();
            
            // 读取输出
            BufferedReader reader = new BufferedReader(
                new InputStreamReader(process.getInputStream())
            );
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println("[Python输出] " + line);
            }
            
            // 等待进程结束
            int exitCode = process.waitFor();
            System.out.println("Python脚本执行结束,退出码: " + exitCode);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Python脚本示例 (analyze.py):

import sys
import argparse

def main():
    # 创建参数解析器
    parser = argparse.ArgumentParser(description='数据分析脚本')
    parser.add_argument('--input', required=True, help='输入文件路径')
    parser.add_argument('--output', required=True, help='输出文件路径')
    parser.add_argument('--verbose', action='store_true', help='详细输出模式')
    
    # 解析参数
    args = parser.parse_args()
    
    print(f"开始分析数据: {args.input}")
    if args.verbose:
        print("详细模式已启用")
    
    # 这里执行实际的数据分析操作...
    
    print(f"分析结果已保存到: {args.output}")

if __name__ == "__main__":
    main()

注意事项与最佳实践

  • 路径处理:使用绝对路径避免找不到文件的问题
  • 参数格式:复杂参数需要正确转义
  • 流处理:及时读取输出流和错误流,避免进程阻塞
  • 错误处理:检查Python脚本的退出状态码
  • 性能考虑:频繁调用时考虑性能开销
  • 跨平台:Windows和Linux/macOS下的路径分隔符不同

两种方法比较

特性 Runtime.exec() ProcessBuilder
易用性 简单直接 需要更多代码
灵活性 有限 高(可设置环境变量、工作目录等)
错误处理 基础 更强大
适用场景 简单脚本调用 复杂调用需求

总结: 两种方法都能实现Java调用Python脚本并传参。对于简单场景,Runtime.exec()足够使用;而对于需要更多控制的场景,ProcessBuilder是更好的选择。无论哪种方法,都要注意参数传递的正确性和错误处理。

发表评论