¿Llamando a Python en Java?

Me pregunto si es posible llamar a las funciones de python desde el código java usando jython, o ¿es solo para llamar código de java desde python?

Jython: Python para la plataforma Java – http://www.jython.org/index.html

Puede llamar fácilmente a las funciones de Python desde el código Java con Jython. Eso es siempre y cuando su propio código de Python se ejecute bajo jython, es decir, no use algunas extensiones C que no sean compatibles.

Si eso funciona para usted, es sin duda la solución más sencilla que puede obtener. De lo contrario, puede usar org.python.util.PythonInterpreter del nuevo soporte de intérprete de Java6.

Un ejemplo simple de la parte superior de mi cabeza, pero debería funcionar, espero: (no se realiza una comprobación de errores por brevedad)

 PythonInterpreter interpreter = new PythonInterpreter(); interpreter.exec("import sys\nsys.path.append('pathToModules if they are not there by default')\nimport yourModule"); // execute a function that takes a string and returns a string PyObject someFunc = interpreter.get("funcName"); PyObject result = someFunc.__call__(new PyString("Test!")); String realResult = (String) result.__tojava__(String.class); 

Hey, pensé que ingresaría mi respuesta a esto aunque fuera tarde. Creo que hay algunas cosas importantes que se deben considerar primero con cuánta fuerza desea tener el enlace entre Java y Python.

En primer lugar, ¿solo desea llamar a funciones o realmente quiere que el código de Python cambie los datos en sus objetos java? Esto es muy importante. Si solo quieres llamar a algún código de Python con o sin argumentos, entonces no es muy difícil. Si tus argumentos son primitivos, lo hace aún más fácil. Sin embargo, si desea que la clase java implemente funciones miembro en Python, que cambian los datos del objeto java, esto no es tan fácil ni sencillo.

En segundo lugar, ¿estamos hablando de cpython o haremos jython? Yo diría que cpython es donde está! Yo recomendaría que esta es la razón por la que Python es tan kool! Teniendo tales altas abstracciones, sin embargo, acceda a c, c ++ cuando sea necesario. Imagínate si pudieras tener eso en java. Esta pregunta ni siquiera vale la pena preguntar si jython está bien porque de todos modos es fácil.

Así que he jugado con los siguientes métodos y los he enumerado de fácil a difícil:

Java a Jython

Ventajas: Trivialmente fácil. Tener referencias reales a objetos java.

Desventajas: No CPython, extremadamente lento!

Jython de Java es muy fácil, y si esto es realmente suficiente, entonces es genial. Sin embargo, es muy lento y no cpython! ¡Vale la pena vivir la vida sin cpython, no lo creo! Puede tener fácilmente el código de Python implementando sus funciones miembro para sus objetos java.

Java a Jython a CPython a través de Pyro

Pyro es el módulo de objeto remoto para python. Tiene algún objeto en un intérprete de cpython, y puede enviar objetos que se transfieren a través de la serialización y también puede devolver objetos a través de este método. Tenga en cuenta que si envía un objeto Python serializado desde jython y luego llama a algunas funciones que cambian los datos en sus miembros, entonces no verá esos cambios en Java. Solo debes recordar enviar los datos que desees de pyro. ¡Creo que esta es la forma más fácil de llegar a cpython! No necesita ningún jni o jna o un gulp o … No necesita conocer ningún c, o c ++. kool eh?

Ventajas: Acceso a cpython, no tan difícil como los siguientes métodos

Desventajas: no se pueden cambiar los datos de los miembros de objetos java directamente desde Python. Es algo indirecto, (jython es hombre medio).

Java a C / C ++ a través de JNI / JNA / SWIG a Python a través de un intérprete integrado (¿quizás utilizando bibliotecas BOOST?)

Dios mío, este método no es para los débiles de corazón. Y puedo decirles que me ha costado mucho lograr esto con un método decente. La razón principal por la que querría hacer esto es para poder ejecutar el código cpython que se reinicia completamente sobre su objeto Java. Hay cosas importantes que se deben considerar antes de decidir probar java de pan (que es como un chimpancé) con python (que es como un caballo). En primer lugar, si golpeas el intérprete que está apagado para tu progtwig! ¡Y no me hagas empezar con problemas de concurrencia! Además, hay una asignación de caldera, creo que he encontrado la mejor configuración para minimizar esta caldera, ¡pero aún es una asignación! Entonces, ¿cómo hacer esto? Considere que C ++ es su intermediario, ¡sus objetos son en realidad objetos c ++! Bien que lo sepas ahora. Simplemente escriba su objeto como si fuera su progtwig como en cpp no ​​java, con los datos a los que desea acceder desde ambos mundos. Luego, puede usar el generador de envoltura llamado swig ( http://www.swig.org/Doc1.3/Java.html ) para hacer que esté disponible para java y comstackr una dll a la que llama System.load (nombre de dll aquí) en Java. ¡Haz que esto funcione primero, luego pasa a la parte difícil! Para llegar a Python necesitas incrustar un intérprete. En primer lugar, sugiero hacer algunos progtwigs de interpretación de hola o este tutorial Incrustar python en C / C. Una vez que tienes ese trabajo, ¡es hora de hacer que el caballo y el mono bailen! Puede enviar su objeto c ++ a python a través de [boost] [3]. Sé que no te he dado el pescado, simplemente te dije dónde encontrar el pez. Algunos punteros a tener en cuenta para esto al comstackr.

Cuando compile boost, necesitará comstackr una biblioteca compartida. Y debe incluir y vincular las cosas que necesita de jdk, es decir, jawt.lib, jvm.lib, (también necesitará el cliente jvm.dll en su ruta cuando inicie la aplicación), además de python27.lib o lo que sea y el boost_python-vc100-mt-1_55.lib. Luego incluya Python / include, jdk / include, boost y use solo bibliotecas compartidas (dlls), de lo contrario, boost tiene un desgarro. Y sí, lo sé todo. Hay tantas maneras en que esto puede ir mal. Así que asegúrate de hacer cada cosa bloque por bloque. Luego júntalos.

No es inteligente tener código python dentro de java. Envuelva su código de Python con un matraz u otro marco web para convertirlo en un microservicio. Haga que su progtwig java pueda llamar a este microservicio (por ejemplo, a través de REST).

Créeme, esto es muy simple y le ahorrará toneladas de problemas. Y los códigos están acoplados de manera flexible, por lo que son escalables.

Varias de las respuestas mencionan que puede usar JNI o ​​JNA para acceder a cpython, pero no recomendaría comenzar desde cero porque ya hay bibliotecas de código abierto para acceder a cpython desde java. Por ejemplo:

  • JEP
  • Guay

Aquí, una biblioteca que le permite escribir sus scripts de Python una vez y decidir qué método de integración (Jython, CPython / PyPy a través de Jep y Py4j) usar en tiempo de ejecución:

https://github.com/subes/invesdwin-context-python

Dado que cada método tiene sus propios beneficios / inconvenientes, como se explica en el enlace.

Depende de qué quieres decir con funciones de python? si se escribieron en cpython, no se pueden llamar directamente, tendrá que usar JNI , pero si se escribieron en Jython, se pueden llamar fácilmente desde java, ya que en última instancia jython genera el código de bytes de Java.

Ahora, cuando digo escrito en cpython o jython, no tiene mucho sentido porque python es python y la mayoría del código se ejecutará en ambas implementaciones a menos que esté utilizando bibliotecas específicas que se basen en cpython o java.

Vea aquí cómo usar el intérprete de Python en Java.

Dependiendo de sus requisitos, las opciones como XML-RPC podrían ser útiles, que se pueden usar para llamar a funciones de forma remota en cualquier idioma compatible con el protocolo.

Puedes llamar a cualquier idioma desde java usando la interfaz nativa de Java

Jython tiene algunas limitaciones:

Hay una serie de diferencias. Primero, los progtwigs Jython no pueden usar los módulos de extensión CPython escritos en C. Estos módulos generalmente tienen archivos con la extensión .so, .pyd o .dll. Si desea utilizar un módulo de este tipo, debe buscar un equivalente escrito en Python puro o Java. Aunque es técnicamente viable admitir dichas extensiones, IronPython lo hace, no hay planes de hacerlo en Jython.

¿Distribuyendo mis scripts de Python como archivos JAR con Jython?

simplemente puede llamar scripts de Python (o bash o Perl) desde Java usando Runtime o ProcessBuilder y pasar la salida a Java:

Ejecutando un script de shell bash en java

Ejecutando línea de comandos en Java

java runtime.getruntime () obtiene resultados al ejecutar un progtwig de línea de comandos