2009年11月19日 星期四

java 透過 PythonInterpreter 執行外部的 py 程式檔

先建立所需要的 java interface

package tw.bennu.feeler.jython.service;
public interface IJyCommand {
public String getName();
}

寫 src/jython/JyCommand.py 去實作 java interface
from tw.bennu.feeler.jython.service import IJyCommand
class JyCommandImpl(IJyCommand):

def __init__(self,cmd):
self.command = cmd

def getName(self):
ret = self.command
print ret
return ret
寫一個 Factory 物件,負責建立PythonInterpreter、讀取*.py、建立及回傳物件實例
public class JyFactory {
// 以 jython 實作的 classes 物件,可用來建立實例
private PyObject jyCommandClass = null;

public JyFactory() {
PyDictionary table = new PyDictionary();
PySystemState state = new PySystemState();
state.setClassLoader(JyFactory.class.getClassLoader());
PythonInterpreter interp = new PythonInterpreter(table, state);
// 讀入 src/jython/*.py
interp.execfile("src/jython/JyCommand.py");
jyCommandClass = interp.get("JyCommandImpl");
}

/**
* 建立一個 IJyCommand 介面的實例 (由JyCommand.py 實作介面內容)
*
* @param name
* @return
*/
public IJyCommand getJyCommand(String name) {
PyObject jyCommandObj = this.jyCommandClass.__call__(new PyString(name));
return (IJyCommand) jyCommandObj.__tojava__(IJyCommand.class);
}
}

JyFactory 解說:先以 interp.get("JyCommandImpl"); 取得 class 物件(只做一次),
再以 class.__call__ 建立實例 obj 物件,最後以 obj.__tojava__轉換回java 物件

public static void main(String[] args){
String name = jythonServImpl.getJyCommand("hello jython").getName();
System.out.println(name);
}

結果會印出 hello jython

沒有留言:

張貼留言