简体   繁体   English

两种方式,java <=> python,使用py4j进行通信

[英]Both ways, java <=> python, communication using py4j

I am using py4j for communication between python and java.I am able to call python method from java side. 我正在使用py4j在python和java之间进行通信。我能够从java端调用python方法。 But from python I am not able to send any object or call java method. 但是从python我无法发送任何对象或调用java方法。 Here is the code i have tried. 这是我尝试过的代码。

My java code: 我的java代码:

public interface IHello {
    public String sayHello();

    public String sayHello(int i, String s);

//    public String frompython();

}

//ExampleClientApplication.java
package py4j.examples;

import py4j.GatewayServer;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class ExampleClientApplication extends Thread {

public void run(){
    System.out.println("thread is running...");
}

public static void main(String[] args) {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    GatewayServer.turnLoggingOff();
    GatewayServer server = new GatewayServer();
    server.start();
    IHello hello = (IHello) server.getPythonServerEntryPoint(new Class[] { IHello.class });
    try {
        System.out.println("Please enter a string");
        String str = br.readLine();
        System.out.println(hello.sayHello(1, str));
    } catch (Exception e) {
        e.printStackTrace();
    }
    ExampleClientApplication t1 = new ExampleClientApplication();
    t1.start();
    //server.shutdown();
  }
}

My python code : 我的python代码:

class SimpleHello(object):
    def sayHello(self, int_value=None, string_value=None):
        print(int_value, string_value)
        return "From python to {0}".format(string_value)

class Java:
    implements = ["py4j.examples.IHello"]

# Make sure that the python code is started first.
# Then execute: java -cp py4j.jar 
py4j.examples.SingleThreadClientApplication

from py4j.java_gateway import JavaGateway, CallbackServerParameters
simple_hello = SimpleHello()

gateway = JavaGateway(
callback_server_parameters=CallbackServerParameters(),
python_server_entry_point=simple_hello)

The send objects problem is easily solved by implementing a getter/eval method in the java interface that is implemented by python, which can then be called from java to get the variable that is requested. 通过在由python实现的java接口中实现getter / eval方法,可以轻松解决发送对象的问题,然后可以从java中调用该方法以获取所请求的变量。 For an example have a look at the py4j implementation here: https://github.com/subes/invesdwin-context-python 例如,在这里查看py4j实现: https : //github.com/subes/invesdwin-context-python

Specifically see the get/eval method implementation here: https://github.com/subes/invesdwin-context-python/blob/master/invesdwin-context-python-parent/invesdwin-context-python-runtime-py4j/src/main/java/de/invesdwin/context/python/runtime/py4j/pool/internal/Py4jInterpreter.py 具体请参见此处的get / eval方法实现: https : //github.com/subes/invesdwin-context-python/blob/master/invesdwin-context-python-parent/invesdwin-context-python-runtime-py4j/src/主/ JAVA / DE / invesdwin /上下文/蟒/运行/ py4j /池/内部/ Py4jInterpreter.py

For the other way around, you would have to do same on the java gateway class and provide a get/eval method that can be called from python. 对于另一种方法,您将必须在java网关类上执行相同的操作,并提供可以从python调用的get / eval方法。 The actual java code could be executed in a ScriptEngine for groovy and the result could be returned to python. 实际的Java代码可以在groovy的ScriptEngine中执行,并且结果可以返回给python。 (see http://docs.groovy-lang.org/1.8.9/html/groovy-jdk/javax/script/ScriptEngine.html ) (请参阅http://docs.groovy-lang.org/1.8.9/html/groovy-jdk/javax/script/ScriptEngine.html

Though it might be a better idea to decide about a master/slave role and only once input the parameters, then execute the code in python and retrieve the results once. 尽管最好只决定一次输入主/从角色,然后再在python中执行代码并检索一次结果,这是一个更好的主意。 Or the other way around if python should be leading. 或者相反,如果python应该领先。 Thus you would reduce the communication overhead a lot. 因此,您将大大减少通信开销。 For a tighter integration without as much of a performance penalty as py4j incurs, you should have a look at https://github.com/mrj0/jep to directly load the python lib into the java process. 为了进行更紧密的集成而不会像py4j那样造成性能损失,请查看https://github.com/mrj0/jep以将python lib直接加载到Java进程中。 Then each call is not as expensive anymore. 然后,每个电话不再昂贵。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM