从Python调用Java
从Python调用Java的最佳方法是什么? (对我来说,jython和RPC都不适用。)
我听说过JCC:http://pypi.python.org/pypi/JCC/1.9 这是一个用于从C++/Python调用Java的C++代码生成器。 不过,这个方法需要为每一个可能的调用都编译一次;我希望能找到其他的解决方案。
我还听说过JPype:http://jpype.sourceforge.net/ 教程在这里:http://www.slideshare.net/onyame/mixing-python-and-java
import jpype
jpype.startJVM(path to jvm.dll, "-ea")
javaPackage = jpype.JPackage("JavaPackageName")
javaClass = javaPackage.JavaClassName
javaObject = javaClass()
javaObject.JavaMethodName()
jpype.shutdownJVM()
这看起来像是我需要的东西。 不过,最后一次发布是在2009年1月,我看到很多人都无法成功编译JPype。
JPype是个死项目吗?
还有其他替代方案吗?
9 个回答
来自 Github 页面:
这是一个 Python 模块,可以通过 JNI 访问 Java 类,就像使用 Python 类一样。
PyJNIus 目前还在开发中。
快速概览
>>> from jnius import autoclass >>> autoclass('java.lang.System').out.println('Hello world') Hello world >>> Stack = autoclass('java.util.Stack') >>> stack = Stack() >>> stack.push('hello') >>> stack.push('world') >>> print stack.pop() world >>> print stack.pop() hello
你也可以使用 Py4J。在它的首页上有一个示例,还有很多文档,不过简单来说,你可以像调用Python方法一样,从你的Python代码中调用Java的方法:
from py4j.java_gateway import JavaGateway
gateway = JavaGateway() # connect to the JVM
java_object = gateway.jvm.mypackage.MyClass() # invoke constructor
other_object = java_object.doThat()
other_object.doThis(1,'abc')
gateway.jvm.java.lang.System.out.println('Hello World!') # call a static method
和Jython不同,Py4J的一部分是在Python虚拟机(VM)中运行的,所以它总是能跟上最新的Python版本,并且你可以使用那些在Jython上运行不太好的库(比如lxml)。另一部分则是在你想要调用的Java虚拟机中运行。
它们之间的通信是通过套接字(sockets)来实现的,而不是通过JNI,Py4J还有自己的协议(用来优化某些情况、管理内存等等)。
免责声明:我是Py4J的作者
这是我对这个问题的总结:5种从Python调用Java的方法
http://baojie.org/blog/2014/06/16/call-java-from-python/ (缓存的内容)
简单来说:Jpype用起来还不错,很多项目(比如python-boilerpipe)都在用它,但Pyjnius比Jpype更快、更简单。
我试过Pyjnius/Jnius、JCC、javabridge、Jpype和Py4j。
Py4j有点难用,因为你需要先启动一个网关,这样就多了一层复杂性。