В обоих случаях, Java <=> Python, общение с использованием py4j

Я использую py4j для связи между python и java. Я могу вызывать метод python со стороны java. Но из 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)

1 ответ

Проблема отправки объектов легко решается путем реализации метода getter / eval в интерфейсе java, который реализуется с помощью python, который затем может быть вызван из 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 gateway и предоставить метод get / eval, который можно вызывать из python. Фактический код Java может быть выполнен в ScriptEngine для groovy, а результат может быть возвращен Python. (см. http://docs.groovy-lang.org/1.8.9/html/groovy-jdk/javax/script/ScriptEngine.html).

Хотя, возможно, было бы лучше определиться с ролью master / slave и только один раз ввести параметры, затем выполнить код на python и получить результаты один раз. Или наоборот, если Python должен быть ведущим. Таким образом, вы значительно уменьшите накладные расходы на связь. Для более тесной интеграции без значительного снижения производительности, которое несет py4j, вы должны взглянуть на https://github.com/mrj0/jep чтобы напрямую загрузить библиотеку python в процесс java. Тогда каждый звонок уже не такой дорогой.

Другие вопросы по тегам