1. 程式人生 > >java和python互相呼叫

java和python互相呼叫

        python作為一種指令碼語言,大量用於測試用例和測試程式碼的編寫,尤其適用於互動式業務場景。實際應用中,很多網管系統做的如交換機、防火牆等裝置升級,往往和裝置互動的命令以及裝置回顯的資訊都是在python指令碼中寫好,java工程直接呼叫相應的python指令碼,執行升級的具體步驟。但是具體的命令一般通過和裝置建立的ssh連線互動,最後python又重新調回java實現的ssh功能。

        Jython是一種完整的語言,而不是一個Java翻譯器或僅僅是一個Python編譯器,它是一個Python語言在Java中的完全實現。Jython也有很多從CPython中繼承的模組庫。最有趣的事情是Jython不像CPython或其他任何高階語言,它提供了對其實現語言的一切存取。所以Jython不僅給你提供了Python的庫,同時也提供了所有的Java類。


        廢話少說,直接上個最簡單的例子,簡單明瞭。

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<String,String> properties)
	{
		//獲取python直譯器
		final PythonInterpreter inter = JythonEnvironment.getInstance().getPythonInterpreter();
		
		//設定python屬性,python指令碼中可以使用
		for (Entry<String,String> 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<String,String> properties = new HashMap<String,String>();
		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()

執行結果