关于JAVA调用Python脚本并传递参数

Posted Smile_Miracle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于JAVA调用Python脚本并传递参数相关的知识,希望对你有一定的参考价值。

JAVA 程序调用python脚本目前存在两种形式。第一种:运用JAVA本身的自带功能;第二种:使用jython Jar包的自带方法来调用python脚本

调用准备:

首先你要在本地或者LINUX环境安装python环境,如果是JYTHON的话需要安装JYTHON,两者二选一,python具体安装转方法详见 WINDOWS安装PYTHON,至于JYTHON安装方式:JYTHON官网下载 Download Jython 2.7.0 - Installer 然后自行安装即可。

 

JAVA自带方法:

 public static void main(String[] args) 
	

  try 
    	 String[] params = new String[] 
         "python","C:\\\\Users\\\\zhonghy\\\\Desktop\\\\zhonghy\\\\demo.py","10","20";
         Process proc=Runtime.getRuntime().exec(params); //执行py文件
         InputStreamReader stdin=new InputStreamReader(proc.getInputStream());
         LineNumberReader input=new LineNumberReader(stdin);
         String line;
         while((line=input.readLine())!=null )
             System.out.println(line);//得到输出
         
         int re = proc.waitFor();
         System.out.println(re);
      catch (Exception e) 
         e.printStackTrace();
     
 

具体返回值可以和脚本提供者协商,常用的返回值为int类型,0代表脚本调用成功,1代表脚本方法调用失败,2代表脚本调用失败

 

Jython方式

我是基于maven构建的项目,所以要引入以下依赖:

<!-- https://mvnrepository.com/artifact/org.python/jython-standalone -->
		<dependency>
		    <groupId>org.python</groupId>
		    <artifactId>jython-standalone</artifactId>
		    <version>2.7.1</version>
		</dependency>

调用方式整理为以下工具类:

package com.mvs.utils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.poi.ss.formula.functions.T;
import org.python.core.PyFunction;
import org.python.core.PyObject;
import org.python.core.PyString;
import org.python.util.PythonInterpreter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**   
 * @ClassName:  JythonUtils   
 * @Description:TODO(jython 工具类)   
 * @author: zhy
 * @Copyright: 2018 Inc. All rights reserved. 
 * 注意:
 */
public class JythonUtils 
	
	private static Logger logger = LoggerFactory.getLogger(JythonUtils.class);
 
 /**   
  * @Title: jythonInit   
  * @Description: TODO(初始化jython)   
  * @param: @return      
  * @return: PythonInterpreter      
  * @throws   
  */
 public static PythonInterpreter jythonInit(String libPath)
        //初始化site 配置
        Properties props = new Properties();
        props.put("python.home", libPath); //python Lib 或 jython Lib,根据系统中该文件目录路径
        props.put("python.console.encoding", "UTF-8");        
        props.put("python.security.respectJavaAccessibility", "false");        
        props.put("python.import.site", "false");
        Properties preprops = System.getProperties();
        PythonInterpreter.initialize(preprops, props, new String[0]);
        //创建PythonInterpreter 对象
        PythonInterpreter interp = new PythonInterpreter();
        return interp;
 
 
 /**   
  * @Title: loadPythonFile   
  * @Description: TODO(加载python 源码文件,)   
  * @param: @param interp
  * @param: @param filePath ,比如:F:\\\\jpython_jar\\\\jpythonTest\\\\pythonTest.py  或/testpython/test.py
  * @param: @return      
  * @return: PythonInterpreter      
  * @throws   
  */
 public static PythonInterpreter loadPythonFile(PythonInterpreter interp, String filePath)
  interp.execfile(filePath);
  return interp;
 
 
 /**   
  * @Title: loadPythonFunc   
  * @Description: TODO(加载python 源码文件中的某个方法)   
  * @param: @param interp
  * @param: @param functionName
  * @param: @return      
  * @return: PyFunction      
  * @throws   
  */
 public static PyFunction loadPythonFunc(PythonInterpreter interp, String functionName)
      //加载方法
     PyFunction func = (PyFunction) interp.get(functionName,PyFunction.class);
      return func;
 
 
 
 /**   
  * @Title: execFunc   
  * @Description: TODO(执行无参方法,返回PyObject)   
  * @param: @param func      
  * @return: PyObject      
  * @throws   
  */
 public static PyObject execFunc(PyFunction func)
  PyObject pyobj = func.__call__();
  return pyobj;
 
 
 /**   
  * @Title: execFuncToString   
  * @Description: TODO(执行无参方法,返回一个字符串)   
  * @param: @param func
  * @param: @return      
  * @return: String      
  * @throws   
  */
 public static String execFuncToString(PyFunction func)
  PyObject pyobj = execFunc(func);
  return (String) pyobj.__tojava__(String.class);
 
 
 /**   
  * @Title: execFuncToString   
  * @Description: TODO(执行有参方法,返回一个字符串)   
  * @param: @param func
  * @param: @param paramName ,参数名
  * @param: @return      
  * @return: String      
  * @throws   
  */
 /*public static String execFuncToString2(PyFunction func, JSONObject object)  
	 String result = "";
	 if(object.get("voiceContent")!=null) 
		 if(object.get("voiceSender")!=null) 
			 func.__call__(new PyString("1"),new PyString("2"),new PyString("3"));
		 
	 
	  return null;
 */
 
/**   
  * @Title: execFuncToInteger   
  * @Description: TODO(执行无参方法,返回一个Integer)   
  * @param: @param func
  * @param: @return      
  * @return: Integer      
  * @throws   
  */
 public Integer execFuncToInteger(PyFunction func)
  PyObject pyobj = execFunc(func);
  return (Integer) pyobj.__tojava__(Integer.class);
 
 
 /**   
  * @Title: execFuncToList   
  * @Description: TODO(执行无参方法,返回一个List)   
  * @param: @param func
  * @param: @return      
  * @return: List<T>      
  * @throws   
  */
 @SuppressWarnings("unchecked")
public List<T> execFuncToList(PyFunction func)
  PyObject pyobj = execFunc(func);
  return (List<T>) pyobj.__tojava__(List.class);
 
 
 /**   
  * @Title: execFuncToMap   
  * @Description: TODO(执行无参方法,返回一个Map<String, Object>)   
  * @param: @param func
  * @param: @return      
  * @return: Map<String,Object>      
  * @throws   
  */
 @SuppressWarnings("unchecked")
public Map<String, Object> execFuncToMap(PyFunction func)
  PyObject pyobj = execFunc(func);
  return (Map<String, Object>) pyobj.__tojava__(Map.class);
 
 
 public void execFuncToByParamsList(PyFunction func, List<T> paramsList)
  
 
 
 public static int sendVoiceByJava(JSONObject object, String alertNum) 
	 int re = 1;
     try 
    	 if(object.get("pythonMethod")==null||object.get("pythonLib")==null||object.get("voiceScript")==null) 
				logger.error("当前配置的python脚本参数错误,请先检查参数.................");
			else 
				 List<String> paramLst = new ArrayList<String>();
				 paramLst.add("python");//
				 paramLst.add((String)object.get("voiceScript"));
				 paramLst.add(object.get("voiceRecevier")==null?null:object.getString("voiceRecevier"));
				 if(object.get("voiceContent")!=null&&object.get("voiceKeys")!=null) 
						String[] params = object.getString("voiceKeys").split(",", -1);
						for(int i = 0;i<params.length;i++) 
							JSONArray parseArray = JSON.parseArray(object.getString("voiceContent"));
							if(parseArray.getJSONObject(i).get(params[i])==null) 
								paramLst.add(null);
							else 
								paramLst.add(parseArray.getJSONObject(i).getString(params[i]));
							
				  
				 logger.info("Python Params Are: "+paramLst.toString());
		         Process process = Runtime.getRuntime().exec((String[])paramLst.toArray());
		        re = process.waitFor();  
			 
			
      catch (Exception e) 
         logger.error("Python脚本调用异常............................", e);
         re = 2;
       
     return re;

 
 
 
 

public static boolean sendVoiceByJython(JSONObject object, String alertNum) 
	    boolean flag = false;
		try 
			if(object.get("pythonMethod")==null||object.get("pythonLib")==null||object.get("voiceScript")==null) 
				logger.error("当前配置的python脚本参数错误,请先检查参数.................");
			else 
				PythonInterpreter interp  = jythonInit(object.getString("pythonLib"));
				//获取py脚本路径
				interp = loadPythonFile(interp,object.getString("voiceScript"));
				//设置参数
				//interp.set("voiceSender", object.get("voiceSender")==null?null:object.getString("voiceSender"));
				interp.set("voiceRecevier", object.get("voiceRecevier")==null?null:object.getString("voiceRecevier"));
				if(object.get("voiceContent")!=null&&object.get("voiceKeys")!=null) 
					String[] params = object.getString("voiceKeys").split(",", -1);
					for(int i = 0;i<params.length;i++) 
						JSONArray parseArray = JSON.parseArray(object.getString("voiceContent"));
						if(parseArray.getJSONObject(i).get(params[i])==null) 
							interp.set(params[i], null);
						else 
							interp.set(params[i], parseArray.getJSONObject(i).getString(params[i]));
						
				
				PyFunction func = loadPythonFunc(interp, object.getString("pythonMethod"));
				PyObject pyObj = func.__call__();
				flag =  (boolean) pyObj.__tojava__(Boolean.class);
			 
			
		 catch (Exception e) 
			logger.error("Python脚本调用异常............................", e);
		
	
	return flag;

 
 public static void main(String[] args) 
	 
	PythonInterpreter interpreter =  jythonInit("D:\\\\Devlop\\\\python");  
     interpreter.execfile("C:\\\\Users\\\\zhonghy\\\\Desktop\\\\zhonghy\\\\demo.py");  
     PyFunction function = (PyFunction)interpreter.get("my_test",PyFunction.class);  
     PyObject pyobject = function.__call__(new PyString("huzhiwei"),new PyString("25")); 
     System.out.println("anwser = " + pyobject.toString()); 

/*   try 
    	 String[] params = new String[] "python","C:\\\\Users\\\\zhonghy\\\\Desktop\\\\zhonghy\\\\demo.py","10","20";
         Process proc=Runtime.getRuntime().exec(params); //执行py文件
         InputStreamReader stdin=new InputStreamReader(proc.getInputStream());
         LineNumberReader input=new LineNumberReader(stdin);
         String line;
         while((line=input.readLine())!=null )
             System.out.println(line);//得到输出
         
         int re = proc.waitFor();
         System.out.println(re);
      catch (Exception e) 
         e.printStackTrace();
     */
 



这里要注意的是你在初始化Jython对象的时候的home参数可以是PYTHON的安装路径也可以是JYTHON的安装路径

测试PY脚本



def my_test(name, age):
    print ("name: "+name)
    print ("age: "+age)
    return "success"

需要注意的是,如果运行出错说你python语法异常,那么你就要好好检查下语法了,python2与3各个版本的语法都是不同的。

运行结果(Jython方式)

name: huzhiwei
age: 25
anwser = success

运行结果(JAVA自带方式)

0

 

需要注意的是:如果你用的是jython初始化的方式制定了一些默认参数是不会报cp0错误的,虽然这个错误不影响程序运行,但是如果你是JAVA形式运行python脚本,那么你需要在RUN CONFIGURATION中指定以下参数:

-Dpython.console.encoding=UTF-8

 

没事可以写一些简单的脚本来测试调用是否成功,这里程序并没有获取到PYTHON输出的数据,具体问题正在检查中,有兴趣的可以留言一起探讨。

以上是关于关于JAVA调用Python脚本并传递参数的主要内容,如果未能解决你的问题,请参考以下文章

Java调用Python脚本并获取返回值

[Python]在python中调用shell脚本,并传入参数-02python操作shell实例

shell调用python脚本,并且向python脚本传递参数

将参数从cmd传递到python脚本[重复]

参数传递:shell脚本调用一个带参数的python函数

从 bash 脚本向 python 传递参数