最近python十分流行,而java也是同样一直火爆。这篇文章介绍如何在java代码中嵌套python代码。既然是两种语言,那么肯定是不能写一段java代码,然后写一段python代码就执行了。java是运行在jvm上的(此处不深入讨论,有兴趣的同学可以参考别的文章。可以粗犷地理解成java代码运行时,计算机产生了一个“机中机”(jvm),而代码实则是在此“机中机”上运行的)。所以我们想到,不妨让python的代码也去jvm上运行。第三方库jython实现了这个功能。jython首先将python代码编译成jvm字节码,然后由jvm来执行编译好的字节码。也就是说,jython是将python代码变成了java代码。这是jython的maven依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/org.python/jython-standalone -->
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.7.0</version>
</dependency>
</dependencies>
- 执行python语句
- 调用python文件
- 与python文件的变量交互
- 与python文件的函数交互
- 与python文件的类交互
执行python片段
public static void main(String[] args) {
PythonInterpreter pi = new PythonInterpreter();
//执行python代码段
pi.exec("print('hello python in java')");
}
运行结果(实际运行时可能有一堆warning,可以忽略)
hello python in java
第2行代码pythoninterpreter就是一个python翻译器,我们实例化一个PythonInterpreter来使用它的方法。exec()方法的作用是执行语句。第4行将python语句作为参数传给exec()方法来执行python语句。
调用python文件
public static void main(String[] args) {
PythonInterpreter pi = new PythonInterpreter();
pi.execfile("src/main/java/test/test/hello.py"); //自己文件的路径
//释放资源
pi.cleanup();
pi.close();
}
我在同一当前项目目录下创建了hello.py文件
print("Hello python in java")
print("你好java中的python")
运行结果(可以感受到运行的还是比较慢的)
Hello python in java
你好java中的python
execfile()方法执行python文件。
与python文件的变量交互
public static void main( String[] args )
{
try (PythonInterpreter pi = new PythonInterpreter()) {
pi.set("c", 2);
pi.execfile("src/main/java/test/test/randomSum.py");
PyObject sum = pi.get("sum");
System.out.println("Sum is: " + sum);
}catch (Exception e){
e.printStackTrace();
}
}
这里也是在同一目录下写了randomSum.py文件。功能是生成随机数求和。
from java.util import Random
r = Random()
sum = 0
for i in xrange(c):
randomNum = r.nextInt()
print randomNum
sum += randomNum
set()方法设置变量.PyObject()生成对象。get()获取变量值。
运行结果
-1352150556
-1975689017
Sum is: -3327839573L
与python文件的函数交互
public static void main(String[] args) {
PythonInterpreter pi = new PythonInterpreter();
pi.execfile("src/main/java/test/test/power.py");
// 调用Python程序中的函数,实例PyFunction获得函数对象
PyFunction pf = pi.get("power", PyFunction.class);
PyObject result = pf.__call__(Py.newInteger(2), Py.newInteger(3)); //__call__方法调用函数
//后面的参数是py文件函数需要的参数
System.out.println(result);
pi.cleanup();
pi.close();
}
同样地需要自己编写power.py文件。功能是求a的b次方。
import math
def power(x, y):
return math.pow(x, y)
输出结果
8.0
与python文件的对象交互
public static void main(String[] args) {
PythonInterpreter pi = new PythonInterpreter();
pi.execfile("src/main/java/test/test/power2.py");
//在Java中调用Python对象实例的方法
String pythonClassName = "Power"; // python类名
String pythonObjName = "pow"; // python对象名
pi.exec(pythonObjName + "=" + pythonClassName + "()"); //用python的语法实例化python对象
PyObject pyObj = pi.get(pythonObjName); // 获取实例化的python对象
// 调用python对象方法,传递参数并接收返回值
PyObject result = pyObj.invoke("power", new PyObject[] {Py.newInteger(2), Py.newInteger(3)});
double power = Py.py2double(result);
System.out.println(power);
pi.cleanup();
pi.close();
}
注释已经写得很详细了,就不单独说了。下面是power2.py文件
import math
class Power(object):
def power(self, x, y):
return math.pow(x,y)
输出结果
8.0
结尾:简单介绍了几种在java文件中调用python代码的方法。主要是应用了第三方库jython,更多的功能可以去jython的官网上去看。到这结束啦。