【问题标题】:Both ways, java <=> python, communication using py4j两种方式,java <=> python,使用py4j通信
【发布时间】:2017-05-24 05:42:42
【问题描述】:

我正在使用 py4j 进行 python 和 java 之间的通信。我可以从 java 端调用 python 方法。但是从 python 我无法发送任何对象或调用 java 方法。这是我尝试过的代码。

我的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();
  }
}

我的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)

【问题讨论】:

  • 您能更具体地谈谈您的问题吗? “无法发送”是什么意思?到目前为止,您尝试过什么?
  • 如果您能够接收到“From python to ...”,则 Python 进程可以明确地与 Java 端进行通信。您确实需要提供更多详细信息(输出、错误消息等)
  • 1.你有缩进错误,我已经更正了。检查您的来源。 2. 你传递了class SimpleHello(),但没有引用def sayHello(...。那么def sayHello(... 将如何调用?

标签: java python py4j


【解决方案1】:

通过在python实现的java接口中实现getter/eval方法很容易解决发送对象问题,然后可以从java调用该方法以获取请求的变量。例如,请查看此处的 py4j 实现:https://github.com/subes/invesdwin-context-python

这里具体看get/eval方法实现: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

反之,您必须在 java 网关类上做同样的事情,并提供一个可以从 python 调用的 get/eval 方法。实际的java代码可以在groovy的ScriptEngine中执行,结果可以返回给python。 (见http://docs.groovy-lang.org/1.8.9/html/groovy-jdk/javax/script/ScriptEngine.html

虽然决定主/从角色可能是一个更好的主意,并且只输入一次参数,然后在 python 中执行代码并检索一次结果。或者如果python应该领先,则反过来。因此,您将大大减少通信开销。为了更紧密的集成而没有 py4j 产生的性能损失,您应该查看https://github.com/mrj0/jep 以将 python 库直接加载到 java 进程中。这样每次通话就不再那么昂贵了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-14
    • 2016-09-27
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    • 2014-11-11
    • 1970-01-01
    • 2014-01-12
    相关资源
    最近更新 更多