2012-04-10 7 views
30

¿Cuál es la forma más fácil de ejecutar un script de Python desde Java y recibir el resultado de ese script? He buscado diferentes bibliotecas como Jepp o Jython, pero la mayoría parece desactualizada. Otro problema con las bibliotecas es que necesito poder incluir fácilmente una biblioteca con el código fuente (aunque no necesito obtener la fuente para la biblioteca) si utilizo una biblioteca.¿Llamar y recibir resultados de la secuencia de comandos de Python en Java?

Debido a esto, ¿la forma más fácil/más efectiva sería simplemente hacer algo como llamar al script con runtime.exec, y luego capturar de algún modo la salida impresa? O, a pesar de que sería muy doloroso para mí, también podría simplemente hacer que la secuencia de comandos de Python salga a un archivo de texto temporal, luego leer el archivo en Java.

Nota: la comunicación real entre Java y Python no es un requisito del problema que estoy tratando de resolver. Sin embargo, esta es la única forma en que puedo pensar para realizar fácilmente lo que se necesita hacer.

+1

probé la respuesta anterior de John Huang, publicado aquí [proyecto de centro git jpserve] (https://github.com/johnhuang-cn/jpserve) Es la mejor solución ya que se vincula a un cliente en java una aplicación real de Python que puede ejecutar sus scripts, archivos, ... Esto es bueno para proyectos súper complejos en los que necesita la última biblioteca de Python actualizada como Tensorflow, ... El único problema es que tiene que hacer todo en una sola sesión (no como en un intérprete), así que tienes que trabajar en preparar tus comentarios a Java. Pero esto es muy fácil en comparación con la instalación de Tensorflow en las bibliotecas java python Gracias [Joh – Dorin

Respuesta

37

No estoy seguro si entiendo su pregunta correctamente, pero siempre que pueda llamar al ejecutable de Python desde la consola y solo quiera capturar su salida en Java, puede usar el método exec() en la clase Java Runtime.

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

Puede leer sobre cómo leer realmente la salida aquí:

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

También hay una biblioteca Apache (el proyecto ejecutivo de Apache) que le puede ayudar con esto. Puede leer más sobre esto aquí:

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

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

+0

] He estado pensando en hacer un motor de flujo de trabajo donde las funciones de flujo de trabajo serían scripts de Python y el motor sería una aplicación basada en Java. ¿Sabrías cuáles serían los costos de rendimiento de llamar continuamente pequeños scripts de Python uno tras otro? – Saky

+1

Ejecutando 'Runtime.getRuntime(). Exec (" python yourapp.py ");' lanzó una excepción: 'java.io.IOException: No se puede ejecutar el programa" python ": CreateProcess error = 2, El sistema no puede encontrar el archivo especificado 'tenga en cuenta que Python es parte de mi variable PATH –

+0

@joeybaruch He resuelto ese problema por punto a la ruta absoluta de mi ejecutable python, es decir 'Runtime.getRuntime(). Exec (" C: \\ Python27 \\ python.exe yourapp.py ")' –

1

puede probar a usar maravilloso. Se ejecuta en la JVM y viene con un gran apoyo para el funcionamiento de los procesos externos y la extracción de la salida:

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

se puede ver en el código tomado del mismo enlace cómo maravilloso hace que sea fácil de obtener el estado de el proceso:

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

he buscado diferentes bibliotecas como Jepp o Jython, pero la mayoría parece estar muy de moda.

Jython no es "una biblioteca"; es una implementación del lenguaje Python en la parte superior de la Máquina Virtual Java. Definitivamente no está desactualizado; el lanzamiento más reciente fue el 24 de febrero de este año. Implementa Python 2.5, lo que significa que le faltarán algunas funciones más recientes, pero honestamente no es muy diferente de 2.7.

Nota: la comunicación real entre Java y Python no es un requisito de la asignación antes mencionada, por lo que esto no me está haciendo los deberes. Sin embargo, esta es la única forma en que puedo pensar para realizar fácilmente lo que se necesita hacer.

Esto parece extremadamente poco probable para una asignación de escuela. Cuéntanos más acerca de lo que estás realmente tratando de hacer.Por lo general, las tareas escolares especifican exactamente qué idiomas usarás para qué, y nunca he oído hablar de uno que involucre más de un idioma. Si así fuera, te dirían si necesitabas establecer este tipo de comunicación, y cómo pensaban que lo hicieras.

+0

Tiene razón en ambos aspectos. De hecho, sabía que Jython todavía está actualizado, simplemente no lo aclaré. En la segunda nota, lo que realmente estoy tratando de hacer es analizar una cadena utilizando expresiones regulares, sin embargo, la expresión que estoy usando no es compatible con Java. Sí, hay formas en que podría hacer esto usando solo Java con expresiones más simples, pero eso significaría más codificación lógica para analizar la cadena, mientras que este método (es decir, la expresión regular actual que estoy usando) me da más o menos exactamente qué Necesito. –

+0

Maldición, bueno, parece que incluso Python no admite las expresiones que intento usar. Supongo que tendré que volver a trabajar después de todo. –

+0

"más código lógico para analizar la cadena" tendrá ** mucho menos esfuerzo sobre todo, sin importar qué dos idiomas desee usar juntos o cómo planea hacerlo. Créeme. ¿Por qué no hace la pregunta en la que realmente se está preguntando, es decir, ** cómo analizar la cadena **?Una vez más, dado que se trata de una tarea escolar, casi con toda seguridad no significa que utilices funciones avanzadas de expresiones regulares. –

21

Puede incluir la biblioteca Jython en su Proyecto Java. Puede download the source code desde el propio proyecto Jython.

Jython does ofrece soporte para JSR-223 que básicamente le permite ejecutar un script de Python desde Java.

Puede usar un ScriptContext para configurar dónde desea enviar su salida de la ejecución.

Por ejemplo, supongamos que tiene la siguiente secuencia de comandos de Python en un archivo llamado numbers.py:

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

Por lo tanto, se puede ejecutar desde Java de la siguiente manera:

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

Y la salida se be:

1 
2 
3 
4 
5 
6 
7 
8 
9 

Siempre que su script de Python sea compatible con Pyth en 2.5 no tendrás ningún problema al ejecutar esto con Jython.

+0

lo siento, pero ¿has usado alguna jython aquí? Todo lo que ha usado son funciones de biblioteca java std? – KillBill

+1

The ScriptEngine necesita jython en la ruta de la clase o bien 'engine' es nulo –

+0

No entiendo. ¿Es numbers.py la ruta completa al script de Python? Esto no funciona para mi – santafebound

4

Me encontré con el mismo problema antes, también lea las respuestas aquí, pero no encuentra ninguna solución de satisfacción puede equilibrar la compatibilidad, el rendimiento y el formato de salida, el Jython no puede trabajar con extender paquetes C y más lento que CPython . Así que finalmente decidí inventar la rueda yo mismo, me tomó 5 noches, espero que pueda ayudarte también: jpserve (https://github.com/johnhuang-cn/jpserve).

JPserve proporciona una forma simple de llamar a Python e intercambiar el resultado por formato JSON, con pocas pérdidas de rendimiento. El siguiente es el código de muestra.

En un primer momento, iniciar jpserve en el lado Python

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

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

A continuación, llamar Pitón de un lado JAVA:

enfoque
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

Es posible que desee leer [Cómo ofrecer bibliotecas personales de código abierto?] (Https://meta.stackexchange.com/q/229085) antes de publicar sobre su proyecto. – ChrisF

+0

Gracias por su sugerencia. –

+0

Noté que después de la ejecución de un script no recuerda sus variables, es decir, por ejemplo, la carga de un archivo de 500 GB debe realizarse en cada llamada. ¿Es posible inicializar algunas variables o mantener las variables recordadas? –

0

Jython

Java se supone que es independiente de la plataforma, y llamar a una aplicación nativa (como Python) no es muy independiente de la plataforma.

Hay una versión de Python (Jython) escrita en Java, que nos permite incrustar Python en nuestros programas de Java.Como suele ocurrir, cuando va a utilizar bibliotecas externas, un obstáculo es compilar y ejecutarlo correctamente, por lo tanto, pasamos por el proceso de creación y ejecución de un simple programa Java con Jython.

Comenzamos por apoderarse de archivo jar jython:

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

copié jython-2.5.3.jar al directorio en mi programa Java iba a ser. Luego escribí el siguiente programa, que hace lo mismo que los dos anteriores; tomar dos números, los envía al pitón, que ellos, después de pitón lo devuelve de nuevo a nuestro programa Java, donde el número se da salida a la pantalla añade:

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

Yo llamo a este archivo "test3.java", salvo , y haga lo siguiente para compilar:

javac -classpath test3.java jython-2.5.3.jar

el siguiente paso es tratar de ejecutarlo, lo que voy a hacer de la siguiente manera:

java-classpath jython-2.5.3.jar :. test3

Ahora, esto nos permite usar Python desde Java, de una manera independiente de la plataforma. Es un poco lento Aún así, es genial, es un intérprete de Python escrito en Java ...

2

Jep es la opción anterior. Incorpora CPython en Java a través de 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"); 
    } 
Cuestiones relacionadas