2012-04-10 23 views
30

Qual è il modo più semplice per eseguire uno script Python da Java e ricevere l'output di tale script? Ho cercato librerie diverse come Jepp o Jython, ma la maggior parte sembra obsoleta. Un altro problema con le librerie è che devo essere in grado di includere facilmente una libreria con il codice sorgente (anche se non ho bisogno di procurarmi la libreria stessa) se uso una libreria.Chiama e ricevi output dallo script Python in Java?

Per questo motivo, il modo più semplice/più efficace consiste semplicemente nel fare qualcosa come chiamare lo script con runtime.exec e in qualche modo acquisire l'output stampato? Oppure, anche se sarebbe molto doloroso per me, potrei anche avere l'output dello script Python in un file di testo temporaneo, quindi leggere il file in Java.

Nota: la comunicazione effettiva tra Java e Python non è un requisito del problema che sto cercando di risolvere. Questo, tuttavia, è l'unico modo in cui posso pensare per eseguire facilmente ciò che deve essere fatto.

+1

ho testato la risposta precedente di Giovanni Huang, pubblicato qui [git progetto hub jpserve] (https://github.com/johnhuang-cn/jpserve) E 'la soluzione migliore perché collega un client java per una vera applicazione Python in grado di eseguire script, file, ... Questo è utile per i progetti super-complessi in cui è necessario l'ultima libreria Python aggiornata come Tensorflow, ... L'unico problema è che devi fare tutto in un'unica sessione (non come in un interprete), quindi devi lavorare per preparare il tuo feedback a java. Ma questo è super facile paragonato all'installazione di Tensorflow nelle librerie java python Grazie [Joh – Dorin

risposta

37

Non sono sicuro di aver compreso correttamente la domanda, ma se è possibile chiamare l'eseguibile Python dalla console e si desidera catturare l'output in Java, è possibile utilizzare il metodo exec() nella classe Java Runtime.

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

si può leggere su come leggere in realtà l'uscita qui:

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

C'è anche una libreria di Apache (il progetto exec Apache) che può aiutare con questo. Si può leggere di più su di esso qui:

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

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

+0

Ho pensato di creare un motore di flusso di lavoro in cui le funzioni del flusso di lavoro fossero script python e il motore fosse un'applicazione basata su Java. Sapresti quali sarebbero i costi delle prestazioni di chiamare continuamente piccoli script python uno dopo l'altro? – Saky

+1

Esecuzione 'Runtime.getRuntime(). Exec (" python yourapp.py ");' ha generato un'eccezione: 'java.io.IOException: impossibile eseguire il programma" python ": errore CreateProcess = 2, il sistema non riesce a trovare il file specificato 'per favore nota che python fa parte della mia variabile PATH –

+0

@joeybaruch Ho risolto quel problema per punto al percorso assoluto del mio eseguibile python, cioè 'Runtime.getRuntime(). Exec (" C: \\ Python27 \\ python.exe yourapp.py ")' –

1

Puoi provare a utilizzare Groovy. Si corre sulla JVM e viene fornito con grande supporto per l'esecuzione di processi esterni ed estraendo l'output:

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

si può vedere in questo codice preso dalla stesso link come Groovy rende facile per ottenere lo status di il processo:

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

ho guardato per le librerie diverse, come Jepp o Jython, ma la maggior parte sembrano essere molto aggiornata.

Jython non è "una libreria"; è un'implementazione del linguaggio Python su Java Virtual Machine. Non è sicuramente obsoleto; la versione più recente è stata il 24 febbraio di quest'anno. Implementa Python 2.5, il che significa che mancheranno un paio di funzionalità più recenti, ma onestamente non è molto diverso dal 2.7.

Nota: la comunicazione effettiva tra Java e Python non è un requisito del suddetto compito, quindi questo non sta facendo i miei compiti per me. Questo, tuttavia, è l'unico modo in cui posso pensare per eseguire facilmente ciò che deve essere fatto.

Questo sembra estremamente improbabile per un compito scolastico. Per favore dicci di più su cosa stai cercando di fare davvero.Di solito, i compiti scolastici specificano esattamente quali lingue userete per cosa, e non ne ho mai sentito uno che abbia coinvolto più di una lingua. Se lo facesse, ti direbbero se avevi bisogno di impostare questo tipo di comunicazione, e in che modo hanno voluto che tu lo facessi.

+0

Hai ragione su entrambi i fronti. In realtà sapevo che Jython è ancora aggiornato, non ho proprio chiarito. Nella seconda nota, quello che sto provando a fare è analizzare una stringa usando le espressioni regolari, tuttavia, l'espressione che sto usando non è supportata in Java. Sì, ci sono modi in cui posso farlo usando solo Java con espressioni più semplici, ma ciò significherebbe più codice logico per analizzare la stringa, mentre questo metodo (cioè l'espressione regolare corrente che sto usando) mi dà praticamente esattamente cosa Ho bisogno. –

+0

Dannazione, beh, sembra che anche Python non supporterà le espressioni che sto cercando di usare. Immagino che dovrò rielaborarlo dopo tutto. –

+0

"più codice logico per analizzare la stringa" sarà ** molto ** meno sforzo su tutto, non importa quali due langauges si desidera utilizzare insieme o come si prevede di farlo. Fidati di me. Perché non fai la domanda che ti stai veramente chiedendo - cioè ** come analizzare la stringa **?Anche in questo caso, dato che si tratta di un incarico scolastico, quasi certamente non significa che tu possa utilizzare le funzioni di regex avanzate. –

21

È possibile includere la libreria nel progetto Java. È possibile download the source code dal progetto Jython stesso.

Jython offre il supporto per JSR-223 che fondamentalmente consente di eseguire uno script Python da Java.

È possibile utilizzare un ScriptContext per configurare dove si desidera inviare l'output dell'esecuzione.

Per esempio, supponiamo di avere il seguente script Python in un file denominato numbers.py:

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

Quindi, è possibile eseguirlo da Java come segue:

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

E l'uscita sarà be:

1 
2 
3 
4 
5 
6 
7 
8 
9 

Finché il tuo script Python è compatibile con Pyth su 2.5 non avrete problemi con questo con Jython.

+0

scusa ma hai usato qualche jython qui? tutto quello che hai usato sono le funzioni della libreria java std? – KillBill

+1

Lo ScriptEngine ha bisogno di jython sul percorso della classe, altrimenti "engine" è nullo –

+0

Non capisco. Numbers.py è il percorso completo dello script Python? Questo non funziona per me. – santafebound

4

Ho già incontrato lo stesso problema, leggere anche le risposte qui, ma non ho trovato alcuna soluzione di soddisfazione in grado di bilanciare l'output di compatibilità, prestazioni e ben formato, Jython non può funzionare con estensioni pacchetti C e più lento di CPython . Così alla fine ho deciso di inventare la ruota da solo, ci sono volute 5 notti, spero che possa aiutarti anche tu: jpserve (https://github.com/johnhuang-cn/jpserve).

JPserve fornisce un modo semplice per chiamare Python e scambiare il risultato con un buon formato JSON, poche perdite di prestazioni. Quello che segue è il codice di esempio.

In un primo momento, iniziare jpserve sul lato Python

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

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

Quindi chiamare Python da Java lato:

approccio
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

È possibile leggere [Come offrire librerie open source personali?] (Https://meta.stackexchange.com/q/229085) prima di pubblicare sul proprio progetto. – ChrisF

+0

Grazie per il tuo suggerimento. –

+0

Ho notato che dopo l'esecuzione di uno script non ricorda le sue variabili, ad esempio il caricamento di un file da 500 GB deve essere eseguito in ogni chiamata. È possibile inizializzare alcune variabili o mantenere le variabili memorizzate? –

0

Jython

Java dovrebbe essere indipendente dalla piattaforma, e chiamare un'applicazione nativa (come python) non è molto indipendente dalla piattaforma.

Esiste una versione di Python (Jython) scritta in Java, che ci consente di incorporare Python nei nostri programmi Java.Come al solito, quando si usano librerie esterne, un ostacolo è compilare ed eseguirlo correttamente, quindi passiamo attraverso il processo di creazione ed esecuzione di un semplice programma Java con Jython.

Iniziamo entrare in possesso di file jar Jython:

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

ho copiato Jython-2.5.3.jar alla directory in cui il mio programma Java sarebbe stato. Poi ho digitato il seguente programma, che fa lo stesso dei due precedenti; prendere due numeri, li invia a python, che poi pitone torna di nuovo al nostro programma Java, dove il numero viene emesso alla schermata aggiunge:

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

Io chiamo questo file "test3.java", salva , e procedere come segue compilarlo:

javac -classpath jython-2.5.3.jar test3.java

il passo successivo è quello di provare a farlo funzionare, cosa che faccio nel seguente modo:

java -classpath jython-2.5.3.jar :. test3

Ora, questo ci consente di utilizzare Python da Java, in modo indipendente dalla piattaforma. È un po 'lento. Eppure, è abbastanza interessante, che si tratti di un interprete Python scritto in Java ...

2

Jep è un'opzione anther. Incorpora CPython in Java tramite 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"); 
    } 
Problemi correlati