1.通过Jython实现调用
Jython简介
Jython主页:http://www.jython.org/
Jython是Python语言在Java平台的实现,本质上,Jython是由Java编写,其是在JVM上实现的Python语言。因此,可以直接通过Jython在Java中调用Python。
到官网https://www.jython.org/download.html下载Jython的jar包或者在maven的pom.xml文件中加入如下代码:
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.7.0</version>
</dependency>
2.通过Java的Runtime实现
直接通过Java的Runtime实现,Runtime类的Runtime.getRuntime()开启进程,执行python脚本文件
3.示例
@RunWith(SpringRunner.class)
@SpringBootTest
public class JythonExampleApplicationTests {
/**
* Jython 在java类中直接执行python语句
*/
@Test
public void test0() {
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec("a='hello world'; ");
interpreter.exec("print a;");
}
/**
* Jython 执行python文件
*/
@Test
public void test1() {
/*************python***************
#coding=utf-8
print("hello world")
**********************************/
/*************python***************
#coding=utf-8
def greeting(name):
print("你好, " + name)
return "你好, " + name
greeting("lnn");
**********************************/
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.execfile("D:\\fun.py");
}
/**
* Jython 执行python文件,调用python方法
*/
@Test
public void test2() {
/*************python***************
#coding=utf-8
def greeting(name):
print("你好, " + name)
return "你好, " + name
***********************************/
PythonInterpreter interpreter = new PythonInterpreter();
// 加载python脚本
interpreter.execfile("D:\\fun.py");
// 第一个参数为期望获得的函数(变量)的名字,第二个参数为期望返回的对象类型
PyFunction pyFunction = interpreter.get("greeting", PyFunction.class);
String name = "wsl";
//调用函数,如果函数需要参数,在Java中必须先将参数转化为对应的“Python类型”
PyObject pyobj = pyFunction.__call__(new PyString(name));
//这里ret可能会乱码
String ret = pyobj.toString();
try {
String newStr = new String(ret.getBytes("iso8859-1"), "utf-8");
System.out.println("the anwser is: " + newStr);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// 报错unindent does not match any outer indentation level
// python对缩进具有严格的要求
// 1、代码前后缩进量不一致
// 2、代码前后缩进符号不一致
// 3、tab与space混用
// 报错SyntaxError: Non-ASCII character in file
// 1, 出现的原因: python的默认编码文件是用ASCII码,没有支持UTF-8,而你的python文件中使用了中文等非英语字符。
// 2,因此,解决的方法,在文件的开头输入如下:
// # -*- coding: UTF-8 -*- 或者 #coding=utf-8
}
/**
* Jython 执行python文件,引用自定义python模块
*/
@Test
public void test3() {
/*************python***************
#coding=utf-8
import fun
def add(a,b):
fun.greeting(str(a))
fun.greeting(str(b))
return a + b
fun.greeting("wsl")
**********************************/
//System.setProperty("python.home", "D:\\tools\\python");
PythonInterpreter interpreter = new PythonInterpreter();
// 引用自定义python模块
PySystemState sys = Py.getSystemState();
sys.path.add("D:\\py_test");//import 模块的文件目录
interpreter.exec("import fun");//添加模块引用 es: import fun
// 加载python脚本
interpreter.execfile("D:\\py_test\\add.py");
// 第一个参数为期望获得的函数(变量)的名字,第二个参数为期望返回的对象类型
PyFunction pyFunction = interpreter.get("add", PyFunction.class);
int a = 5, b = 10;
//调用函数,如果函数需要参数,在Java中必须先将参数转化为对应的“Python类型”
PyObject pyobj = pyFunction.__call__(new PyInteger(a), new PyInteger(b));
System.out.println("the anwser is: " + pyobj);
// 报错unindent does not match any outer indentation level
// python对缩进具有严格的要求
// 1、代码前后缩进量不一致
// 2、代码前后缩进符号不一致
// 3、tab与space混用
// 报错SyntaxError: Non-ASCII character in file
// 1, 出现的原因: python的默认编码文件是用ASCII码,没有支持UTF-8,而你的python文件中使用了中文等非英语字符。
// 2,因此,解决的方法,在文件的开头输入如下:
// # -*- coding: UTF-8 -*- 或者 #coding=utf-8
}
/**
* Jython 执行python文件,引用自定义+系统python模块
*/
@Test
public void test4() {
/*************python***************
#coding=utf-8
import fun
import datetime
def add(a, b):
print("方法调用时间:" + str(datetime.datetime.now()))
fun.greeting(str(a))
fun.greeting(str(b))
return a + b
fun.greeting("wsl")
print("当前时间:" +str(datetime.datetime.now()))
**********************************/
//System.setProperty("python.home", "D:\\tools\\python");
PythonInterpreter interpreter = new PythonInterpreter();
// 引用自定义python模块
PySystemState sys = Py.getSystemState();
sys.path.add("D:\\py_test");//import 模块的文件目录
interpreter.exec("import fun");//添加模块引用 es: import fun
// 加载python脚本
interpreter.execfile("D:\\py_test\\add.py");
// 第一个参数为期望获得的函数(变量)的名字,第二个参数为期望返回的对象类型
PyFunction pyFunction = interpreter.get("add", PyFunction.class);
int a = 5, b = 10;
//调用函数,如果函数需要参数,在Java中必须先将参数转化为对应的“Python类型”
PyObject pyobj = pyFunction.__call__(new PyInteger(a), new PyInteger(b));
System.out.println("the anwser is: " + pyobj);
// 报错unindent does not match any outer indentation level
// python对缩进具有严格的要求
// 1、代码前后缩进量不一致
// 2、代码前后缩进符号不一致
// 3、tab与space混用
// 报错SyntaxError: Non-ASCII character in file
// 1, 出现的原因: python的默认编码文件是用ASCII码,没有支持UTF-8,而你的python文件中使用了中文等非英语字符。
// 2,因此,解决的方法,在文件的开头输入如下:
// # -*- coding: UTF-8 -*- 或者 #coding=utf-8
}
/**
* 通过Runtime.getRuntime()开启进程来执行脚本文件
*/
@Test
public void test5() {
// python安装目录 cmd pip install requests
/*************python***************
#coding=utf-8
import urllib.request
response = urllib.request.urlopen('http://www.baidu.com')
html =str(response.read(),'utf-8')
print(html)
**********************************/
// args[0]表示要执行的是python 脚本 ,args[1] 脚本文件的全路径
String[] arguments = new String[]{"D:\\tools\\python\\python.exe", "D:\\py_test\\request.py"};
try {
Process process = Runtime.getRuntime().exec(arguments);
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
// 在此需要注意的一点,java代码中的process.waitFor()返回值为0表示我们调用python脚本成功,
// 返回值为1表示调用python脚本失败,这和我们通常意义上见到的0与1定义正好相反。
int re = process.waitFor();
System.out.println(re);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 通过Runtime.getRuntime()开启进程来执行脚本文件,传参
*/
@Test
public void test6() {
/*************python***************
#coding=utf-8
def greeting(name):
print("你好, " + name)
greeting(sys.argv[1]) #sys.argv[0] 存储的是py文件自身的路径,故接受参数从sys.argv[1]开始
greeting(sys.argv[2])
**********************************/
try {
// 因此在python代码中我们需要通过sys.argv的方式来拿到java代码中传递过来的参数。
int a = 18;
int b = 23;
//String[] args = new String[] { "D:\\tools\\python\\python.exe", "D:\\py_test\\test.py", String.valueOf(a), String.valueOf(b) };
// args[0]表示要执行的是python 脚本 ,args[1] 脚本文件的全路径
String[] args = new String[]{"D:\\tools\\python\\python.exe", "D:\\py_test\\test.py", String.valueOf(a), String.valueOf(b)};
// sys.argv[0] 存储的是py文件自身的路径,故接受参数从sys.argv[1]开始
Process pr = Runtime.getRuntime().exec(args);
BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream(), "GBK"));// 解决乱码
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
// 在此需要注意的一点,java代码中的process.waitFor()返回值为0表示我们调用python脚本成功,
// 返回值为1表示调用python脚本失败,这和我们通常意义上见到的0与1定义正好相反。
int waitFor = pr.waitFor();
System.out.println(waitFor);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 通过Runtime.getRuntime()开启进程来执行脚本文件,json传参
*/
@Test
public void test7() {
// python安装目录 cmd pip install demjson
// https://www.runoob.com/python/python-json.html
/*************python***************
#coding=utf-8
import sys
import demjson
str=sys.argv[1] #str得到的key没有双引号
print(str)
#直接用json.loads(str)报错
data=demjson.decode(str)
print(data)
**********************************/
try {
// 因此在python代码中我们需要通过sys.argv的方式来拿到java代码中传递过来的参数。
Map<String, String> map = new HashMap<>();
map.put("name", "wsl");
map.put("age", "25");
String arg = JSON.toJSONString(map);
arg = "'" + arg + "'";//json 参数要加单引号,没有单引号解析失败
// args[0]表示要执行的是python 脚本 ,args[1] 脚本文件的全路径
String[] args = new String[]{"D:\\tools\\python\\python.exe", "D:\\py_test\\request.py", arg};
// sys.argv[0] 存储的是py文件自身的路径,故接受参数从sys.argv[1]开始
Process pr = Runtime.getRuntime().exec(args);
BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream(), "GBK"));// 解决乱码
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
// 在此需要注意的一点,java代码中的process.waitFor()返回值为0表示我们调用python脚本成功,
// 返回值为1表示调用python脚本失败,这和我们通常意义上见到的0与1定义正好相反。
int waitFor = pr.waitFor();
System.out.println(waitFor);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 通过Runtime.getRuntime()开启进程来执行脚本文件,argparse接收参数
*/
@Test
public void test8() {
// python安装目录 cmd pip install demjson
// https://www.runoob.com/python/python-json.html
/*************python***************
# coding=utf-8
import argparse
import sys
import demjson
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("--input_path", type=str, help="image input path")
parser.add_argument("--output_image", type=str, help="result image output path")
parser.add_argument("--output_json", type=str, help="result json output path")
args = parser.parse_args()
print(args.__str__())
**********************************/
try {
String[] args = new String[]{"D:\\tools\\python\\python.exe", "D:\\py_test\\request.py"
,"--input_path=/home/data/rB8BlV6FPcSAVLTmAAGQQ-II1tI341.jpg"
,"--output_image=/home/img/341.jpg"
,"--output_json=/home/json/341.txt"};
// args[0]表示要执行的是python 脚本 ,args[1] 脚本文件的全路径
//String[] args = new String[]{"D:\\tools\\python\\python.exe", "D:\\py_test\\request.py", envp};
// sys.argv[0] 存储的是py文件自身的路径,故接受参数从sys.argv[1]开始
Process pr = Runtime.getRuntime().exec(args);
BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream(), "GBK"));// 解决乱码
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
// 在此需要注意的一点,java代码中的process.waitFor()返回值为0表示我们调用python脚本成功,
// 返回值为1表示调用python脚本失败,这和我们通常意义上见到的0与1定义正好相反。
int waitFor = pr.waitFor();
System.out.println(waitFor);
} catch (Exception e) {
e.printStackTrace();
}
}
}