2012-04-10 3 views
30

Was ist der einfachste Weg, ein Python-Skript von Java auszuführen und die Ausgabe dieses Skripts zu erhalten? Ich habe nach verschiedenen Bibliotheken wie Jepp oder Jython gesucht, aber die meisten scheinen veraltet zu sein. Ein anderes Problem mit den Bibliotheken ist, dass ich in der Lage sein muss, eine Bibliothek mit dem Quellcode einfach aufzunehmen (obwohl ich für die Bibliothek selbst keine Quelle benötige), wenn ich eine Bibliothek verwende.Aufruf und Ausgabe von Python-Skript in Java?

Aus diesem Grund wäre die einfachste/effektivste Möglichkeit, einfach etwas wie das Skript mit runtime.exec zu starten, und dann irgendwie gedruckte Ausgabe erfassen? Oder, obwohl es für mich sehr schmerzhaft wäre, könnte ich das Python-Skript auch nur in eine temporäre Textdatei ausgeben lassen und dann die Datei in Java lesen.

Hinweis: Die tatsächliche Kommunikation zwischen Java und Python ist keine Voraussetzung für das Problem, das ich lösen möchte. Dies ist jedoch der einzige Weg, den ich mir vorstellen kann, um einfach auszuführen, was zu tun ist.

+1

ich die vorherige Antwort von John Huang getestet, hier veröffentlicht [git hub-Projekt jpserve] (https://github.com/johnhuang-cn/jpserve) Es ist die beste Lösung, weil es einen Java-Client Links zu eine echte Python-Anwendung, die Ihre Skripte, Dateien, ... ausführen kann Dies ist gut für super komplexe Projekte, wo Sie zuletzt aktualisiert Python-Bibliothek wie Tensorflow, ... Das einzige Problem ist, dass Sie alle in einer Sitzung zu tun haben (nicht wie in einem Dolmetscher), so müssen Sie daran arbeiten, Ihr Feedback zurück zu Java vorzubereiten. Aber das ist sehr einfach im Vergleich zur Installation von Tensorflow in Java-Python-Bibliotheken Vielen Dank [Joh – Dorin

Antwort

37

Nicht sicher, ob ich Ihre Frage richtig verstehe, aber vorausgesetzt, dass Sie die ausführbare Python-Datei über die Konsole aufrufen können und nur ihre Ausgabe in Java erfassen möchten, können Sie die exec()-Methode in der Klasse Java Runtime verwenden.

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

können Sie nachlesen, wie man tatsächlich die Ausgabe hier zu lesen:

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

Es gibt auch eine Apache-Bibliothek (die Apache exec-Projekt), die Ihnen dabei helfen können. Hier können Sie mehr darüber lesen:

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

http://commons.apache.org/exec/

+0

Ich habe darüber nachgedacht, eine Workflow-Engine zu machen, wo die Workflow-Funktionen Python-Skripte und die Engine selbst eine Java-basierte Anwendung wäre. Würdest du wissen, wie hoch die Kosten für den fortlaufenden Aufruf von kleinen Python-Skripten sind? – Saky

+1

Running 'Runtime.getRuntime(). Exec (" python yourapp.py ");' hat eine Ausnahme ausgelöst: 'java.io.IOException: Kann das Programm" python "nicht ausführen: CreateProcess error = 2, Das System kann die angegebene Datei nicht finden 'Bitte beachten Sie, dass Python ist Teil meiner PATH-Variable –

+0

@joeybaruch Ich habe dieses Problem nach dem Punkt auf den absoluten Pfad meiner ausführbaren Python, Ie gelöst 'Runtime.getRuntime(). Exec (" C: \\ Python27 \\ python.exe yourapp.py ")' –

1

Sie versuchen, groovy verwenden, können. Es läuft auf der JVM und es kommt mit großer Unterstützung für externe Prozesse laufen und Extrahieren der Ausgabe:

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

Sie in diesem Code sehen können aus dem gleichen Link genommen, wie stark macht es einfach, den Status zu erhalten der Prozess:

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

ich habe für verschiedene Bibliotheken wie Jepp oder Jython aussehen, aber die meisten scheinen sehr veraltet zu sein.

Jython ist nicht "eine Bibliothek"; Es ist eine Implementierung der Python-Sprache auf der Java Virtual Machine. Es ist definitiv nicht veraltet; Die letzte Veröffentlichung war der 24. Februar dieses Jahres. Es implementiert Python 2.5, was bedeutet, dass Sie ein paar neuere Funktionen vermissen werden, aber es ist ehrlich gesagt nicht viel anders als 2.7.

Hinweis: Die eigentliche Kommunikation zwischen Java und Python ist keine Voraussetzung für die oben genannte Aufgabe, also macht dies meine Hausaufgaben nicht für mich. Dies ist jedoch der einzige Weg, den ich mir vorstellen kann, um einfach auszuführen, was zu tun ist.

Dies scheint extrem unwahrscheinlich für eine Schulaufgabe. Bitte erzähl uns mehr darüber, was du bist wirklich versuchen zu tun.Üblicherweise legen Schulaufgaben genau fest, welche Sprachen Sie für welche Sprache verwenden werden, und ich habe noch nie von einer gehört, die mehr als eine Sprache umfasst. Wenn dies der Fall wäre, würden sie Ihnen sagen, ob Sie diese Art von Kommunikation einrichten müssen und wie sie es geplant haben.

+0

Sie haben in beiden Punkten Recht. Ich wusste tatsächlich, dass Jython immer noch aktualisiert wird, ich habe es nicht wirklich geklärt. In der zweiten Anmerkung versuche ich, eine Zeichenfolge mit regulären Ausdrücken zu analysieren. Der von mir verwendete Ausdruck wird jedoch in Java nicht unterstützt. Ja, es gibt Möglichkeiten, wie ich dies nur mit Java mit einfacheren Ausdrücken tun könnte, aber das würde mehr Logikcodierung zum Analysieren der Zeichenfolge bedeuten, während diese Methode (dh der aktuelle reguläre Ausdruck, den ich verwende) mir ziemlich genau was gibt Ich brauche. –

+0

Verdammt, nun, es sieht so aus, als würde Python die Ausdrücke, die ich benutzen möchte, nicht unterstützen. Ich denke, ich werde es doch noch überarbeiten müssen. –

+0

"mehr Logik-Codierung, um die Zeichenfolge zu analysieren" wird ** viel ** weniger Aufwand insgesamt sein, egal welche zwei Sprachen Sie verwenden möchten oder wie Sie es vorhaben. Vertrau mir. Warum stellst du nicht die Frage, über die du dich wirklich wunderst - d. H. ** wie parst du die Saite **?Da es sich hier um eine Schulaufgabe handelt, bedeutet das höchstwahrscheinlich nicht, dass Sie fortgeschrittene Regex-Funktionen verwenden. –

21

Sie können die Bibliothek Jython in Ihr Java-Projekt einschließen. Sie können download the source code aus dem Jython-Projekt selbst.

Jython bietet Unterstützung für JSR-223, die im Grunde können Sie ein Python-Skript von Java ausführen.

Sie können eine ScriptContext verwenden, um zu konfigurieren, wo Sie Ihre Ausgabe der Ausführung senden möchten.

Zum Beispiel nehmen wir an, Sie das folgende Python-Skript in einer Datei numbers.py benannt haben:

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

So können Sie es von Java wie folgt:

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

und der Ausgang wird be:

1 
2 
3 
4 
5 
6 
7 
8 
9 

Solange Ihr Python-Skript mit Pyth kompatibel ist auf 2.5 werden Sie keine Probleme haben, dies mit Jython auszuführen.

+0

Entschuldigung, aber hast du irgendeinen Jython hier benutzt? Alles, was Sie benutzt haben, sind Java-Standard-Bibliotheksfunktionen? – KillBill

+1

Die ScriptEngine benötigt jython auf dem Klassenpfad sonst 'engine' ist null –

+0

Ich verstehe nicht. Ist numbers.py der vollständige Pfad zum Python-Skript? Das funktioniert nicht für mich. – santafebound

4

Ich habe das gleiche Problem vor, lesen Sie auch die Antworten hier, aber keine gefunden, die Lösung zufrieden stellen kann die Kompatibilität, Leistung und gut formatieren Ausgabe ausgleichen, kann die Jython nicht mit C-Paketen erweitern und langsamer als CPython . So entschied ich mich schließlich, das Rad selbst zu erfinden, es dauerte meine 5 Nächte, ich hoffe, dass es Ihnen auch helfen kann: jpserve (https://github.com/johnhuang-cn/jpserve).

JPserve bietet eine einfache Möglichkeit, Python aufzurufen und das Ergebnis durch JSON gut zu formatieren, wenig Performanceverlust. Folgendes ist der Beispielcode.

Zunächst starten jpserve auf Python Seite

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

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

Dann Python rufen von der Seite JAVA:

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 
+0

Bevor Sie über Ihr Projekt berichten, sollten Sie [Wie bieten Sie persönliche Open-Source-Bibliotheken an?] (Https://meta.stackexchange.com/q/229085) lesen. – ChrisF

+0

Danke für Ihren Vorschlag. –

+0

Mir ist aufgefallen, dass nach der Ausführung eines Skripts es sich nicht an seine Variablen erinnert, d. H. Zum Beispiel muss bei jedem Aufruf eine 500-GB-Datei geladen werden. Ist es möglich, einige Variablen zu initialisieren oder die Variablen beizubehalten? –

0

Jython Ansatz

Java soll plattformunabhängig sein, und eine native Anwendung (wie Python) aufzurufen, ist nicht sehr plattformunabhängig.

Es gibt eine Version von Python (Jython), die in Java geschrieben ist, die es uns ermöglicht, Python in unsere Java-Programme einzubetten.Wie auch immer, wenn Sie externe Bibliotheken verwenden, besteht eine Hürde darin, sie zu kompilieren und korrekt auszuführen. Deshalb durchlaufen wir ein einfaches Java-Programm mit Jython.

Wir beginnen halten jython jar-Datei bekommen:

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

I jython-2.5.3.jar in das Verzeichnis, wo mein Java-Programm werden würde kopiert. Dann tippte ich das folgende Programm ein, das dasselbe wie die vorherigen zwei tut; nehmen Sie zwei Zahlen, sendet sie an Python, die sie hinzufügt, dann Python kehrt es zurück zu unserem Java-Programm, wo sich die Zahl auf dem Bildschirm ausgegeben wird:

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

ich diese Datei „test3.java“ nennen, speichern es, und gehen sie wie folgt, es zu kompilieren:

javac -classpath jython-2.5.3.jar test3.java

der nächste Schritt ist zu versuchen, es zu laufen, was ich tun, um die folgende Art und Weise:

java -classpath jython-2.5.3.jar :. test3

Jetzt können wir Python aus Java plattformunabhängig verwenden. Es ist irgendwie langsam. Trotzdem ist es irgendwie cool, dass es ein Python-Interpreter ist, geschrieben in Java ...

2

Jep ist eine andere Option. Es bettet CPython in Java durch 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"); 
    }