Вызывать модули Python из Java - PullRequest
7 голосов
/ 18 января 2009

У меня есть Python-интерфейс библиотеки графов, написанный на C-igraph (название библиотеки). Мне нужно вызвать модули Python, относящиеся к этой библиотеке графов, из кода Java. Похоже, ядро ​​библиотеки находится в c. Это ядро ​​было импортировано в Python, а интерфейсы к функциям, встроенным в ядро, доступны в Python. Остальная часть кода моего проекта написана на Java, и поэтому я хотел бы также вызывать графовые функции с помощью Java. Jython - который позволяет вам вызывать модули Python с помощью Java, был одним из вариантов. Я продолжал пытаться Jython обнаружить, что он не будет работать в моем случае, поскольку основной код находится в C, и Jython не будет поддерживать все, что импортируется как ac dll в python Я также подумал о том, чтобы выбрать метод вызова графа непосредственно в c. Это без прохождения кода Python. Я предполагаю, что должно быть что-то, что позволяет вам вызывать c-код из Java, хотя я не очень хорош в C, поэтому я не пошел на это. Мне кажется, что в крайнем случае я выполняю интерпретатор Python из командной строки, используя Java. Но это грязно и бесстыдно. Также, чтобы иметь дело с результатами, полученными в коде Python, мне нужно будет записать результаты в файл и прочитать их обратно в Java. Опять грязный путь. Есть что-то, что кто-нибудь может мне предложить? Спасибо каждому, кто уделил время.


Спасибо, Игал за ответ. Я посмотрел на это. На первый взгляд кажется, что он просто вызывает скрипт Python.

Jep jep = new Jep(false, SCRIPT_PATH, cl);
jep.set("query", query);
jep.runScript(SCRIPT_PATH + file);
jep.close();

Разве это не очень похоже на то, что мы сделали бы, если бы вызывали интерпретатор python из командной строки через код Java.

Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("python test.py");

Беспокойство вызывает то, как я могу использовать результаты, сгенерированные скриптом Python. Наивный способ - записать их в файл и прочитать на Java. Я ищу более разумный подход. Спасибо за предложение в любом случае.

Ответы [ 3 ]

4 голосов
/ 25 марта 2010

Если вы хотите вызывать функции C из Java, JNA (Java Native Access) - это, вероятно, путь. JNA позволяет вам вызывать функции в нативных библиотеках без необходимости написания связующего кода на C (как это было бы необходимо при использовании JNI) и автоматически сопоставляет примитивные типы данных в Java и C. Простой пример может выглядеть следующим образом:

import com.sun.jna.Native;
import com.sun.jna.Library;

public class PrintfWrapper {
    public interface CLibrary extends Library {
        CLibrary INSTANCE = (CLibrary)Native.loadLibrary("c", CLibrary.class);
        void printf(String formatString, Object... args);
    }

    public static void main(String[] args) {
        CLibrary.INSTANCE.printf("Hello, world\n");
    }
}

Однако с igraph все усложняется, потому что igraph использует много структур данных, которые не могут быть отображены непосредственно в их аналоги Java. Существует проект под названием JNAerator , который должен быть в состоянии генерировать источник JNA из заголовочных файлов igraph, но я никогда не пробовал его, и есть вероятность, что результаты все же потребуют некоторой ручной настройки.

Также обратите внимание, что Java-интерфейс для igraph разрабатывается медленно, но неуклонно и может стать полезным через несколько месяцев или около того.

4 голосов
/ 18 января 2009

Никогда не пробовал. Но недавно я наткнулся на проект под названием Jepp , который может вас заинтересовать.

Jepp встраивает CPython в Java. Его безопасно использовать в многопоточной среде, он достаточно быстрый, а его стабильность - главная особенность и цель.

2 голосов
/ 29 августа 2012

Вы можете использовать jep.getValue (), чтобы получить значение из глобального словаря скрипта.

Существуют предостережения, касающиеся уровней области действия в Python, поэтому большинство людей считают более понятным передать класс Java в Python и установить возвращаемое значение в этом экземпляре в Python. После завершения сценария код Java будет иметь результат.

Например:

==> Java

class ReturnValueClass {
   public int scriptResult;
};
ReturnValueClass value = new ReturnValueClass();
jep.set("retval", value);

==> Python

# do something
pass
# write the return value
retval.scriptResult = some_python_value

==> Java

System.out.println(value.scriptResult);

Надеюсь, это поможет,

Майк (я написал Jep)

...