Python调用Java与Java中调用Python

Python中调用Java

参考:
JPype:实现在python中调用JAVA

1.安装

首先系统中Python和Java版本最好都是32位或者都为64位,否则可能出现错误。

pip install jpype1

可能需要安装VC for python27:https://www.microsoft.com/en-us/download/confirmation.aspx?id=44266

2.简单测试

test.java

public class test{
    public String value="";

    public test(String value){
        this.value=value;
    }
    public String getValue(){
        return this.value;
    }
    public void setValue(String value){
        this.value=value;
    }
}

编译成test.class文件

test.py

from jpype import *
import os

classpath = os.path.join(os.path.abspath('.'), 'D:/WorkSpace/')  
startJVM("C:/Program Files/Java/jdk1.8.0_161/jre/bin/server/jvm.dll","-ea", "-Djava.class.path=%s" % (classpath))  
javaClass=JClass('test')
value="oldValue"
javaInstance=javaClass(value)
print javaInstance.getValue()
javaInstance.setValue("newValue")
print javaInstance.getValue()

print java.lang.System.out.println("hello world")
shutdownJVM()

Java中调用Python

1.安装Jython(原 JPython )

参考:
在 Java 中调用 Python 代码
在Java中调用Python

测试程序:

package testcode;
import org.python.util.PythonInterpreter;

public class testjython {
    public static void main(String[] args) {
        PythonInterpreter interpreter = new PythonInterpreter();
        interpreter.exec("print('hello')");
    }
}

在使用jython2.7.0版本时出现如下的错误:

Exception in thread "main" java.lang.IllegalArgumentException: Cannot create PyString with non-byte value
    at org.python.core.PyString.(PyString.java:64)
    at org.python.core.PyString.(PyString.java:70)
    at org.python.core.Py.newString(Py.java:641)
    at org.python.core.PySystemState.initRegistry(PySystemState.java:800)
    at org.python.core.PySystemState.doInitialize(PySystemState.java:1045)
    at org.python.core.PySystemState.initialize(PySystemState.java:974)
    at org.python.core.PySystemState.initialize(PySystemState.java:930)
    at org.python.core.PySystemState.initialize(PySystemState.java:925)
    at org.python.core.PySystemState.initialize(PySystemState.java:920)
    at org.python.core.PySystemState.initialize(PySystemState.java:916)
    at org.python.core.ThreadStateMapping.getThreadState(ThreadStateMapping.java:32)
    at org.python.core.Py.getThreadState(Py.java:1440)
    at org.python.core.Py.getThreadState(Py.java:1436)
    at org.python.core.Py.getSystemState(Py.java:1456)
    at org.python.util.PythonInterpreter.(PythonInterpreter.java:105)
    at org.python.util.PythonInterpreter.(PythonInterpreter.java:94)
    at org.python.util.PythonInterpreter.(PythonInterpreter.java:71)
    at testcode.testjython.main(testjython.java:6)

错误的原因:

In case you use Jython 2.7.0, one could use the following code to use any of Unicode strings within your code:
PyString str = Py.newStringOrUnicode(“颜军”)
from stackoverflow

直接换成jython-2.5.2版本执行正常。

2.在jython中执行python脚本

interpreter.execfile("D:/labs/mytest/hello.py");  

如上,将 exec 改为 execfile 就可以了。需要注意的是,这个 .py 文件不能含有第三方模块,因为这个“ Python 脚本”最终还是在 JVM 环境下执行的(而非依赖于本地计算机环境),如果 .py 程序中有用到第三方模块(例如 NumPy)将会报错:java ImportError: No module named xxx

3.在 JVM 中调用 Python 编写的函数

test.py

def hello():
    return 'Hello'

testjython.java

package testcode;
import org.python.core.PyFunction;
import org.python.core.PyObject;
import org.python.util.PythonInterpreter;

public class testjython {
    public static void main(String[] args) {
        PythonInterpreter interpreter = new PythonInterpreter();
        interpreter.execfile("D:/WorkSpace/test.py");
        // 第一个参数为期望获得的函数(变量)的名字,第二个参数为期望返回的对象类型
        PyFunction pyFunction = interpreter.get("hello", PyFunction.class); 
        PyObject pyObject = pyFunction.__call__(); // 调用函数

        System.out.println(pyObject);
    }
}

即便只是调用一个函数,也必须先加载这个 .py 文件,之后再通过 Jython 包中所定义的类获取、调用这个函数。

如果函数需要参数,在 Java 中必须先将参数转化为对应的“ Python 类型”(姑且可以称作 Jython 类型,例如:

__call__(new PyInteger(a), new PyInteger(b))

a,b的类型均为 Java 中的 int 型,还有一些 Jython 类型诸如:
PyList

4.高级调用

参考在Java中调用Python

你可能感兴趣的:(Python语言,Java)