java和python互相呼叫
阿新 • • 發佈:2019-01-11
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()