java和python互相调用

        python作为一种脚本语言,大量用于测试用例和测试代码的编写,尤其适用于交互式业务场景。实际应用中,很多网管系统做的如交换机、防火墙等设备升级,往往和设备交互的命令以及设备回显的信息都是在python脚本中写好,java工程直接调用相应的python脚本,执行升级的具体步骤。但是具体的命令一般通过和设备建立的ssh连接交互,最后python又重新调回java实现的ssh功能。

        Jython是一种完整的语言,而不是一个Java翻译器或仅仅是一个Python编译器,它是一个Python语言在Java中的完全实现。Jython也有很多从CPython中继承的模块库。最有趣的事情是Jython不像CPython或其他任何高级语言,它提供了对其实现语言的一切存取。所以Jython不仅给你提供了Python的库,同时也提供了所有的Java类。

        java和python的互相调用,就需要用到Jython,可在该连接下载Jython相关jar包:https://repo1.maven.org/maven2/org/python/jython。

        废话少说,直接上个最简单的例子,简单明了。

Jython环境类

package com.webim.test.jython;

import org.python.core.PySystemState;
import org.python.util.PythonInterpreter;

/**
 * Jython环境,生存python解释器
 * @author webim
 *
 */
public final class JythonEnvironment
{
	private static JythonEnvironment INSTANCE = new JythonEnvironment();
	
	/**
	 * 私有构造方法
	 */
	private JythonEnvironment()
	{
	}
	
	/**
	 * 获取单例
	 * @return JythonEnvironment
	 */
	public static JythonEnvironment getInstance()
	{
		return INSTANCE;
	}
	
	/**
	 * 获取python系统状态,可根据需要指定classloader/sys.stdin/sys.stdout等
	 * @return PySystemState
	 */
	private PySystemState getPySystemState()
	{
		PySystemState.initialize();
		final PySystemState py = new PySystemState();
		py.setClassLoader(getClass().getClassLoader());
		return py;
	}
	
	/**
	 * 获取python解释器
	 * @return PythonInterpreter
	 */
	public PythonInterpreter getPythonInterpreter()
	{
		PythonInterpreter inter = new PythonInterpreter(null, getPySystemState());
		return inter;
	}
}


java调用python

package com.webim.test.jython;

import java.util.Map;
import java.util.Map.Entry;

import org.python.util.PythonInterpreter;
/*enum的这个用法,可以作为变种的安全单例,值得借鉴哦 ^_^ */
public enum ExecPython
{
	INSTANCE;
	
	public void execute(String scriptFile, Map properties)
	{
		//获取python解释器
		final PythonInterpreter inter = JythonEnvironment.getInstance().getPythonInterpreter();
		
		//设置python属性,python脚本中可以使用
		for (Entry entry : properties.entrySet())
		{
			inter.set(entry.getKey(), entry.getValue());
		}
		
		try
		{
			//通过python解释器调用python脚本
			inter.execfile(scriptFile);
		}
		catch (Exception e)
		{
			System.out.println("ExecPython encounter exception:" + e);
		}
	}
}

供python调用的java类

package com.webim.test.jython;

/**
 * 供python脚本调用的java类
 * @author webim
 *
 */
public class SayHello
{
	private String userName;

	public String getUserName()
	{
		return userName;
	}

	public void setUserName(String userName)
	{
		this.userName = userName;
	}
	
	public void say(int i)
	{
		System.out.println(i + ":Hello " + userName);
	}
}

测试代码

package com.webim.test.jython;

import java.util.HashMap;
import java.util.Map;

/**
 * 测试java和python的调用流程
 * @author webim
 *
 */
public enum TestExecPython
{
	INSTANCE;
	
	public void test()
	{
		String scriptFile = "test.py";
		Map properties = new HashMap();
		properties.put("userName", "Demo");
		
		ExecPython.INSTANCE.execute(scriptFile, properties);
	}
}

main方法类

package com.webim.test.main;

import com.webim.test.jython.TestExecPython;

public class Main 
{
	public static void main(String[] args) 
	{
		TestExecPython.INSTANCE.test();
	}

}
python脚本
#unicode=UTF-8

#################################################
#通过java package导入java类
from com.webim.test.jython import SayHello

execpy = SayHello()

#################################################
#将python属性传入后续调用的java实例
execpy.setUserName(userName)

def say():
    execpy.say(5)
    return

say()


执行结果

java和python互相调用_第1张图片

你可能感兴趣的:(java)