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的設計師說一句
标題