用Jython实现解释执行的Java类
(转载请注明来源于 金庆的专栏)
用Jython可以实现预编译成Java字节流的Java类,需用Jythonc进行编译。
不过更方便的用法是直接用Jython实现嵌入式的类,不需要编译。
一方面是编译很麻烦,另一面预编译并没有带来速度上的优势。
Jythonc编译程序在Jython2.3版中将不再包含。
JDK6已经新增了脚本引擎,可以使用JavaScript,不过使用Jython脚本更令人激动。
本例jyinterface项目包含4个文件:
-Main.java
-EmployeeType.java 对象接口定义
-Employee.py Python实现
-EmployeeFactory.java 对象工厂,生成一个Java对象
//
EmployeeType.java
package
jyinterface.interfaces;

public
interface
EmployeeType
{
public String getEmployeeFirst();
public String getEmployeeLast();
public String getEmployeeId();
}
#
Employee.py
from
jyinterface.interfaces
import
EmployeeType

class
Employee(EmployeeType):
def
__init__
(self, first, last, id):
self.first
=
first
self.last
=
last
self.id
=
id

def
getEmployeeFirst(self):
return
self.first

def
getEmployeeLast(self):
return
self.last

def
getEmployeeId(self):
return
self.id
//
EmployeeFactory.java
package
jyinterface.factory;

import
jyinterface.interfaces.EmployeeType;
import
org.python.core.Py;
import
org.python.core.PyObject;
import
org.python.core.PyString;
import
org.python.util.PythonInterpreter;

public
class
EmployeeFactory
{

public EmployeeFactory() {
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec("from Employee import Employee");
jyEmployeeClass = interpreter.get("Employee");
}

public EmployeeType create(String first, String last, String id) {
PyObject pyObj = jyEmployeeClass.__call__(new PyString(first),
new PyString(last), new PyString(id));
return (EmployeeType)pyObj.__tojava__(EmployeeType.class);
}

private PyObject jyEmployeeClass;
}
注意:Employee.py必须在sys.path路径,这样才能导入。
如将Employee.py放在运行目录,并在jython的registry文件中的python.path添加“.”。
或直接放在jython的Lib目录下。
//
Main.java
package
jyinterface;

import
jyinterface.factory.EmployeeFactory;
import
jyinterface.interfaces.EmployeeType;

public
class
Main
{

private static void print(EmployeeType employee) {
System.out.println("Name: " + employee.getEmployeeFirst() + " "
+ employee.getEmployeeLast());
System.out.println("Id: " + employee.getEmployeeId());
}

public static void main(String[] args) {
EmployeeFactory factory = new EmployeeFactory();
print(factory.create("Josh", "Juneau", "1"));
print(factory.create("Charlie", "Groves", "2"));
}
}
参考:
[1] Accessing Jython from Java Without Using jythonc
[2] Simple and Efficient Jython Object Factories
[2]中会产生一个类型转换错误:
return (EmployeeType)jyEmployeeClass.__call__(...
PyObject应该不能直接转成java对象的,不知作者为什么会这样。
[1]使用execfile()来运行py文件,也可以转成exec("import " + module)
以避免每生成一个对象就运行一遍。
但是也有好处,即可以实时更改py文件立即生效。
而import的文件会缓存,必须显示调用reload()才会重新导入。
Python/C的内嵌接口中好像没有__tojava__()这样的函数,能在语言之间转换对象类型。
看上去只能处理PyObject对象.
(还在摸索中,用Python扩展C++接口应该可以实现。可能boost::python会有。)
(转载请注明来源于 金庆的专栏)
用Jython可以实现预编译成Java字节流的Java类,需用Jythonc进行编译。
不过更方便的用法是直接用Jython实现嵌入式的类,不需要编译。
一方面是编译很麻烦,另一面预编译并没有带来速度上的优势。
Jythonc编译程序在Jython2.3版中将不再包含。
JDK6已经新增了脚本引擎,可以使用JavaScript,不过使用Jython脚本更令人激动。
本例jyinterface项目包含4个文件:
-Main.java
-EmployeeType.java 对象接口定义
-Employee.py Python实现
-EmployeeFactory.java 对象工厂,生成一个Java对象





















































注意:Employee.py必须在sys.path路径,这样才能导入。
如将Employee.py放在运行目录,并在jython的registry文件中的python.path添加“.”。
或直接放在jython的Lib目录下。





















参考:
[1] Accessing Jython from Java Without Using jythonc
[2] Simple and Efficient Jython Object Factories
[2]中会产生一个类型转换错误:
return (EmployeeType)jyEmployeeClass.__call__(...
PyObject应该不能直接转成java对象的,不知作者为什么会这样。
[1]使用execfile()来运行py文件,也可以转成exec("import " + module)
以避免每生成一个对象就运行一遍。
但是也有好处,即可以实时更改py文件立即生效。
而import的文件会缓存,必须显示调用reload()才会重新导入。
Python/C的内嵌接口中好像没有__tojava__()这样的函数,能在语言之间转换对象类型。
看上去只能处理PyObject对象.
(还在摸索中,用Python扩展C++接口应该可以实现。可能boost::python会有。)