web-dev-qa-db-fra.com

Appelez et recevez la sortie de Python en Java?)

Quel est le moyen le plus simple d’exécuter un script Python à partir de Java et de recevoir le résultat de ce script?). J'ai cherché différentes bibliothèques comme Jepp ou Jython, mais la plupart semblent périmées. Un autre problème avec les bibliothèques, c’est que j’ai besoin de pouvoir inclure facilement une bibliothèque avec le code source (bien que je n’ai pas besoin de source pour la bibliothèque elle-même) si j’utilise une bibliothèque.

De ce fait, le moyen le plus simple et le plus efficace serait-il simplement de faire quelque chose comme appeler le script avec runtime.exec, puis capturer en quelque sorte la sortie imprimée? Ou bien, même si cela serait très pénible pour moi, je pourrais aussi simplement avoir le script Python) en sortie dans un fichier texte temporaire, puis lire le fichier en Java.

Remarque: la communication réelle entre Java et Python n'est pas une exigence du problème que j'essaie de résoudre. Cependant, c'est le seul moyen que je peux penser à effectuer facilement ce qui doit être fait.

46
404 Not Found

Pas sûr que je comprenne bien votre question, mais à condition que vous puissiez appeler l'exécutable Python à partir de la console et que vous souhaitez simplement capturer sa sortie en Java, vous pouvez utiliser le exec() méthode dans la classe Java Runtime.

Process p = Runtime.getRuntime().exec("python yourapp.py");

Vous pouvez lire comment lire le résultat ici:

http://www.devdaily.com/Java/edu/pj/pj010016

Il existe également une bibliothèque Apache (le projet Apache exec) qui peut vous aider. Vous pouvez en lire plus à ce sujet ici:

http://www.devdaily.com/Java/java-exec-processbuilder-process-1

http://commons.Apache.org/exec/

56
Sevas

Vous pouvez inclure la bibliothèque Jython dans votre Java. Vous pouvez télécharger le code source à partir du projet Jython lui-même.

Jython offre un support pour JSR-22 qui vous permet de lancer un script Python à partir de Java.

Vous pouvez utiliser un ScriptContext pour configurer l'endroit où vous voulez envoyer votre sortie de l'exécution.

Par exemple, supposons que vous ayez le script Python) suivant dans un fichier nommé numbers.py:

for i in range(1,10):
    print(i)

Vous pouvez donc l’exécuter à partir de Java comme suit:

public static void main(String[] args) throws ScriptException, IOException {

    StringWriter writer = new StringWriter(); //ouput will be stored here

    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptContext context = new SimpleScriptContext();

    context.setWriter(writer); //configures output redirection
    ScriptEngine engine = manager.getEngineByName("python");
    engine.eval(new FileReader("numbers.py"), context);
    System.out.println(writer.toString()); 
}

Et le résultat sera:

1
2
3
4
5
6
7
8
9

Tant que votre script Python est compatible avec Python 2.5), vous ne rencontrerez aucun problème à l'exécuter avec Jython.

29
Edwin Dalorzo

J'ai déjà rencontré le même problème auparavant, lisez également les réponses ici, mais je n'ai trouvé aucune solution satisfaisante permettant d'équilibrer la compatibilité, les performances et le format de sortie, Jython ne peut pas fonctionner avec des packages C étendus et plus lents que CPython. Alors finalement j'ai décidé d'inventer la roue moi-même, cela a pris mes 5 nuits, j'espère que cela pourra vous aider aussi: jpserve ( https://github.com/johnhuang-cn/jpserve ).

JPserve offre un moyen simple d’appeler Python et d’échanger le résultat par un format JSON de puits, avec quelques pertes de performances. Voici un exemple de code.

Au début, démarrez jpserve du côté Python

>>> from jpserve.jpserve import JPServe
>>> serve = JPServe(("localhost", 8888))
>>> serve.start()

INFO:JPServe:JPServe starting...
INFO:JPServe:JPServe listening in localhost 8888

Ensuite, appelez Python à partir de Java side:

PyServeContext.init("localhost", 8888);
PyExecutor executor = PyServeContext.getExecutor();
script = "a = 2\n"
    + "b = 3\n"
    + "_result_ = a * b";

PyResult rs = executor.exec(script);
System.out.println("Result: " + rs.getResult());

---
Result: 6
8
John Huang

J'ai cherché différentes bibliothèques comme Jepp ou Jython, mais la plupart semblent être très obsolètes.

Jython n'est pas "une bibliothèque"; c’est une implémentation du langage Python en plus de la Java. Elle n’est certainement pas obsolète; la version la plus récente date du 24 février. Cette année, il implémente Python 2.5, ce qui signifie qu'il vous manquera quelques fonctionnalités plus récentes, mais honnêtement, il n’est pas très différent de la version 2.7.

Remarque: la communication réelle entre Java et Python n'est pas une exigence de l'affectation susmentionnée. Par conséquent, cela ne me permet pas de faire mon devoir. C'est, Cependant, c'est le seul moyen auquel je peux penser pour effectuer facilement ce qui doit être fait.

Cela semble extrêmement peu probable pour un travail scolaire. Dites-nous en plus à propos de ce que vous essayez réellement . Habituellement, les devoirs de l’école spécifient exactement les langues que vous utiliserez pour quoi et je n’en ai jamais entendu parler. Si c'était le cas, ils vous diraient si vous aviez besoin de mettre en place ce type de communication et comment ils avaient l'intention de le faire.

5
Karl Knechtel

Jep est une autre option. Il incorpore CPython dans Java via JNI.

import jep.Jep;
//...
    try(Jep jep = new Jep(false)) {
        jep.eval("s = 'hello world'");
        jep.eval("print(s)");
        jep.eval("a = 1 + 2");
        Long a = (Long) jep.getValue("a");
    }
2
Ariel

Approche Jython

Java est supposé être indépendant de la plate-forme et appeler une application native (comme python) n'est pas très indépendant de la plate-forme.

Il existe une version de Python (Jython) qui est écrite en Java, ce qui nous permet d’intégrer Python dans notre Java Comme d'habitude, lorsque vous utilisez des librairies externes, vous devez compiler et l'exécuter correctement, c'est pourquoi nous allons construire et exécuter un programme simple Java avec Jython.

Nous commençons par mettre la main sur le fichier jython jar:

http://www.jython.org/downloads.html

J'ai copié jython-2.5.3.jar dans le répertoire où devait se trouver mon programme Java. Ensuite, j'ai tapé le programme suivant, qui fait la même chose que les deux précédents; prenez deux chiffres , les envoie à python, qui les ajoute, puis python le renvoie à notre Java, où le nombre est affiché à l'écran:

import org.python.util.PythonInterpreter; 
import org.python.core.*; 

class test3{
    public static void main(String a[]){

        PythonInterpreter python = new PythonInterpreter();

        int number1 = 10;
        int number2 = 32;
        python.set("number1", new PyInteger(number1));
        python.set("number2", new PyInteger(number2));
        python.exec("number3 = number1+number2");
        PyObject number3 = python.get("number3");
        System.out.println("val : "+number3.toString());
    }
}

J'appelle ce fichier "test3.Java", enregistrez-le et procédez comme suit pour le compiler:

javac -classpath jython-2.5.3.jar test3.Java

La prochaine étape consiste à essayer de l'exécuter, ce que je fais de la manière suivante:

Java -classpath jython-2.5.3.jar :. test3

Cela nous permet maintenant d’utiliser Python de Java, d’une manière indépendante de la plate-forme. C’est un peu lent. Pourtant, c’est plutôt cool que ce soit un Python interprète écrit en Java ...

2

Vous pouvez essayer d'utiliser groovy. Il fonctionne sur la machine virtuelle Java et offre un excellent support pour l'exécution de processus externes et l'extraction de la sortie:

http://groovy.codehaus.org/Executing+External+Processes+From+Groovy

Vous pouvez voir dans ce code tiré du même lien à quel point groovy facilite l'obtention du statut du processus:

println "return code: ${ proc.exitValue()}"
println "stderr: ${proc.err.text}"
println "stdout: ${proc.in.text}" // *out* from the external program is *in* for groovy
1
txominpelu

Tout d'abord, je recommanderais d'utiliser ProcessBuilder (depuis la version 1.5)
L'utilisation simple est décrite ici
https://stackoverflow.com/a/14483787
Pour des exemples plus complexes, voir
http://www.javaworld.com/article/2071275/core-Java/when-runtime-exec---won-t.html

J'ai rencontré un problème lors du lancement du script Python de Java, le script produisait trop de sortie au format standard et tout se passait mal.

1
partTimeNinja

Le meilleur moyen consiste à utiliser Apache Commons Exec comme je l’utilise pour une production sans problème, même dans l’environnement Java 8), car il vous permet d’exécuter tout processus externe (y compris python, etc.). bash etc) à synchronous et asynchronous à l'aide de chiens de garde.

 CommandLine cmdLine = new CommandLine("python");
 cmdLine.addArgument("/my/python/script/script.py");
 DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();

 ExecuteWatchdog watchdog = new ExecuteWatchdog(60*1000);
 Executor executor = new DefaultExecutor();
 executor.setExitValue(1);
 executor.setWatchdog(watchdog);
 executor.execute(cmdLine, resultHandler);

 // some time later the result handler callback was invoked so we
 // can safely request the exit value
 resultHandler.waitFor();

Le code source complet pour un POC petit mais complet est partagé ici, ce qui répond à une autre préoccupation de ce post ;

https://github.com/raohammad/externalprocessfromjava.git

0
khawarizmi