jython的版本和python都是一一对应的,jython现在更新到了2.7,对应的也就是python2.7.
jython有安装板和独立版,安装板的就像python,需要安装到主机使用,独立版的就是一个jar包,可以在cmd中运行,也可以直接放在java项目中使用,
下载jython Standalone独立版
添加到java项目中
然后创建解析器
package demo3;
import org.python.core.*;
import org.python.util.PythonInterpreter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Properties;
public class jythonshellInter {
public String name;
public PythonInterpreter interpreter;
public jythonshellInter() {
}
public jythonshellInter(String name) {
this.name = name;
jythonInit();
}
public void jythonInit() {
//初始化site 配置
Properties props = new Properties();
props.put("python.console.encoding", "UTF-8");
props.put("python.home", "/lib/jython-standalone-2.7.2b2.jar"); //python Lib 或 jython Lib,根据系统中该文件目录路径
props.put("python.security.respectJavaAccessibility", "false");
props.put("python.import.site", "false");
Properties preprops = System.getProperties();
PythonInterpreter.initialize(preprops, props, new String[0]);
PySystemState sys = Py.getSystemState();
sys.path.add(System.getProperty("user.dir") + "");
//创建PythonInterpreter 对象
interpreter = new PythonInterpreter();
}
/**
* 执行命令
*
* @param cmd
*/
public boolean execute(String cmd) {
PyString str = Py.newStringUTF8(cmd);
boolean falg;
try {
interpreter.exec(str);
falg = true;
} catch (PyException e) {
System.out.println(e.type + "\t" + e.value);
falg = false;
}
return falg;
}
public boolean execFile(File file) {
boolean flag;
try {
FileInputStream fileInputStream = new FileInputStream(file);
interpreter.execfile(fileInputStream);
flag = true;
} catch (FileNotFoundException e) {
e.printStackTrace();
flag = true;
} catch (PyException e) {
System.out.println(e.type + "\n" + e.value);
flag = true;
}
return flag;
}
public void loadFile(String filePath) {
try {
interpreter.execfile(filePath);
} catch (PyException e) {
e.printStackTrace();
}
}
/**
* 获得方法的类型
*
* @param interpreter
* @param funcName
* @return
*/
public PyFunction loadPuthonFunc(PythonInterpreter interpreter, String funcName) {
PyFunction pyFunction = interpreter.get(funcName, PyFunction.class);
return pyFunction;
}
/**
* 执行无参数方法
* 返回obj
*
* @param function
* @return
*/
public Object execFunc(PyFunction function) {
PyObject pyObject = null;
try {
pyObject = function.__call__();
} catch (PyException e) {
e.printStackTrace();
}
return pyObject.__tojava__(Object.class);
}
/**
* 执行多参数下的方法
*
* @param function
* @param values
* @return
*/
public Object execFuncOfArr(PyFunction function, String... values) {
PyString[] strings = new PyString[values.length];
for (int i = 0; i < strings.length; i++) {
strings[i] = Py.newString(values[i]);
}
PyObject pyObject = null;
try {
pyObject = function.__call__(strings);
} catch (PyException e) {
e.printStackTrace();
}
return pyObject.__tojava__(Object.class);
}
/**
* 取出在解析器保存的数据
*
* @param name
* @return
*/
public Object getData(String name) {
PyObject pyObject = interpreter.get(name);
return pyObject.__tojava__(Object.class);
}
}
测试一下,
jython启动了,但没有输出,报错不识别这个命令,
当然不识别了,我没有给helloworld加引号,字符串当然要加引号才能识别了
这样就可以了,
新建一个脚本
test.py
#coding=utf8
def testStrAdd(str):
return str+"123"
jythonTest测试类
package demo3;
import org.python.core.PyFunction;
import java.io.File;
public class jythonTest {
public static void main(String[] args) {
jythonshellInter shellInter = new jythonshellInter("");
String path = System.getProperty("user.dir") + "/resources/test.py";
shellInter.loadFile(path);
PyFunction function = shellInter.loadPuthonFunc(shellInter.interpreter, "testStrAdd");
Object hello = shellInter.execFuncOfArr(function, "hello");
System.out.println(hello);
}
}
多参数试一下
# coding=utf8
def testStrAdd(*str):
a = ""
for i in str:
a = a + i + "*"
return a
package demo3;
import org.python.core.PyFunction;
import java.io.File;
public class jythonTest {
public static void main(String[] args) {
jythonshellInter shellInter = new jythonshellInter("");
String path = System.getProperty("user.dir") + "/resources/test.py";
shellInter.loadFile(path);
PyFunction function = shellInter.loadPuthonFunc(shellInter.interpreter, "testStrAdd");
Object hello = shellInter.execFuncOfArr(function, "hello", "world", "!");
System.out.println(hello);
}
}
测试一下
这里要注意的是,jython是2版本的python,解析的全部是ASCII编码 ,对中文的支持很差,(不过其他国家语言也一样),并且像特殊符号也不能写入,比如西格玛,兰姆达这样的希腊字符,都是不能输入的,
jython在执行python脚本的时候,我们可以直接将对象存入解析器中,这样就可以实现大容量或者不规整无法使用json写出的数据传入py脚本,直接操作对象肯定比json二次录入要高效的多,
传入py文件的对象,要使用java的表达式进行操作,
新建一个user类
package demo3;
public class User {
String name;
int age;
double hight;
public User(String name, int age, double hight) {
this.name = name;
this.age = age;
this.hight = hight;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getHight() {
return hight;
}
public void setHight(double hight) {
this.hight = hight;
}
}
写一个user的集合放入jython的解析器中
package demo3;
import org.python.core.PyFunction;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class jythonTest {
public static void main(String[] args) {
jythonshellInter shellInter = new jythonshellInter("");
String path = System.getProperty("user.dir") + "/resources/test.py";
shellInter.loadFile(path);
PyFunction function = shellInter.loadPuthonFunc(shellInter.interpreter, "userWriter");
List<User> users = new ArrayList<>();
users.add(new User("faker", 20, 182.0));
users.add(new User("uzi", 21, 183.0));
users.add(new User("jax", 22, 184.0));
shellInter.interpreter.set("data", users);
String filePath = "D:\\";
String fileName = "text.txt";
Object hello = shellInter.execFuncOfArr(function, filePath, fileName);
System.out.println(hello);
}
}
新建一个文件写出的方法,解析java对象,并写出对象属性到文件
# coding=utf8
import codecs
def testStrAdd(*str):
a = ""
for i in str:
a = a + i + "*"
return a
def userWriter(filePath, fileName):
try:
file = codecs.open(filePath + "/" + fileName, "w")
wire = ""
for user in data:
wire = user.getName() + "\t" + str(user.getAge()) + "\t" + str(user.getHight()) + "\n"
file.write(wire)
finally:
file.close()
测试下
成功写出
jython的运用方法有很多种,但是ascli码的限制让传值有很大的限制,py.newStringUTF8()就是个骗人的玩意,并不能发送中文
说起这个传值,就不得不提一下python2时代 的各种坑爹了
之前在写出方法中,一直采用的直接转成json当做参数传给方法,json也是字符串嘛,奈何io流毕竟小水管,没办法一次发送字节超过20万的字符串,后来就想到传byte数组,我转成byte数组总没问题吧,这样一来,中文问题都解决了,啊,我真是太机智了
too young too simple
直接报错,不识别非ascll码的值,
看的我一脸懵逼啊,字节数组不应该啊,都是数字啊,
隐约觉得那里不对劲
在我点开python2.5的源码的时候,我差点就要失意体前屈了
bytes=str
好嘛,直接将字符串赋给字节数组,真是天人合一,天下无敌啊
每次想起这件事,我都想深切对python的设计师说一句
![](https://i-blog.csdnimg.cn/blog_migrate/91a3bad92f2e7dc3443919b28de584cb.jpeg)