2012-01-17 10 views
70

Mi chiedo se sia possibile chiamare le funzioni python dal codice java usando jython, o è solo per chiamare il codice java da python?Chiamare Python in Java?

+2

Si prega di dare un'occhiata a una domanda simile e leggere la risposta. http://bytes.com/topic/python/answers/22390-executing-jython-function-java – AlexR

risposta

72

si può facilmente richiamare funzioni Python da codice Java con Jython. Questo è fintanto che il codice Python stesso viene eseguito con jython, cioè non usa alcune estensioni c non supportate.

Se questo funziona per te, è sicuramente la soluzione più semplice che puoi ottenere. Altrimenti puoi usare org.python.util.PythonInterpreter dal nuovo supporto per interprete Java6.

Un semplice esempio dalla cima della mia testa - ma dovrebbe funzionare spero: (nessun controllo degli errori fatto per brevità)

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

Ho installato JYthon, o presumo di averlo fatto, e continuo a provare a eseguire il codice che hai delineato ma che è stato evidenziato come errore. L'installazione di Jython deve andare in una cartella specifica, nelle cartelle python o java? – Shahab

+1

@Shahab Non molto utile se non si dice quale errore appare .. – Voo

+0

Non ci sono errori, sto solo facendo fatica a integrare Jython in Netbeans – Shahab

3

È possibile chiamare qualsiasi lingua dalla Java utilizzando Java Native Interface

+6

Qualsiasi linguaggio che può essere chiamato da c. Bene, ok, python può, ma Jython è una soluzione molto più semplice (o che usa PyInterpreter in j6 +). Non è così banale scrivere il codice per chiamare le funzioni python da c. – Voo

4

Dipende da cosa si intende per funzioni Python? se sono stati scritti in cpython non è possibile chiamarli direttamente, sarà necessario utilizzare JNI, ma se sono stati scritti in Jython, è possibile chiamarli facilmente da java, poiché jython alla fine genera codice byte java.

Ora, quando dico scritto in cpython o jython, non ha molto senso perché python è python e la maggior parte del codice verrà eseguito su entrambe le implementazioni a meno che non si stiano utilizzando librerie specifiche basate su cpython o java.

Vedi qui how to use Python interpreter in Java.

3

A seconda delle esigenze, le opzioni come XML-RPC potrebbero essere utili, che può essere utilizzato per chiamare a distanza le funzioni praticamente in qualsiasi lingua che supporta il protocollo.

37

Ehi, ho pensato di inserire la mia risposta a questo anche se è tardi. Penso che ci siano alcune cose importanti da considerare prima con quanto forte desideri il collegamento tra java e python.

In primo luogo Si desidera solo chiamare le funzioni o in realtà si desidera che il codice Python modifichi i dati negli oggetti java? Questo è molto importante. Se si desidera chiamare solo un codice Python con o senza argomenti, non è molto difficile. Se i tuoi argomenti sono primitivi, lo rende ancora più facile. Tuttavia, se si desidera disporre di funzioni membro dell'attuale classe java in python, che modificano i dati dell'oggetto java, non è così semplice o diretto.

In secondo luogo stiamo parlando di cpython o farà jython? Direi che cpython è dove è! Vorrei difendere questo è il motivo per cui Python è così kool! Avere astrazioni così alte tuttavia l'accesso a c, C++ quando necessario. Immagina se potessi averlo in java. Questa domanda non vale nemmeno la pena di chiedersi se jython è ok, perché allora è comunque facile.

così ho giocato con i seguenti metodi, e, elencata da facile a difficile:

Java per Jython

Vantaggi: banalmente facile. Avere riferimenti reali a oggetti java

Svantaggi: Nessun CPython, estremamente lento!

Jython di java è così facile, e se questo è davvero sufficiente, allora è grandioso. Comunque è molto lento e non cpython! La vita vale la pena vivere senza cpython, io non la penso così! Puoi facilmente avere codice Python che implementa le tue funzioni membro per te oggetti java.

Java per Jython a CPython via Pyro

Pyro è il modulo di oggetto remoto per pitone. Hai qualche oggetto su un interprete cpython, e puoi inviarlo oggetti che vengono trasferiti tramite serializzazione e può anche restituire oggetti tramite questo metodo. Si noti che se si invia un oggetto python serializzato da jython e poi si chiamano alcune funzioni che modificano i dati nei suoi membri, non si vedranno queste modifiche in java. Devi solo ricordarti di rispedire i dati che desideri da pyro. Questo credo sia il modo più semplice per arrivare a cpython! Non hai bisogno di jni o jna o swig o .... Non hai bisogno di conoscere alcun c, o C++. kool huh?

Vantaggi: accesso al CPython, non è così difficile come seguenti metodi

Svantaggi: non possono cambiare i dati dei membri di oggetti Java direttamente da Python. È un po 'indiretto, (jython è l'uomo medio).

Java per C/C++ tramite JNI/JNA/SWIG per Python tramite interprete embedded (magari usando librerie BOOST?)

OMG questo metodo non è per i deboli di cuore. E posso dirvi che mi ci è voluto molto tempo per ottenere questo risultato con un metodo decente. Il motivo principale per cui vorresti farlo è che puoi eseguire il codice cpython che ti dà il massimo sull'oggetto java. Ci sono importanti cose da considerare prima di decidere di provare e pane java (che è come uno scimpanzé) con python (che è come un cavallo). Innanzitutto se si blocca l'interprete che si spegne per il tuo programma! E non farmi iniziare sui problemi di concorrenza! Inoltre, vi è l'assegnazione della caldaia, credo di aver trovato la migliore configurazione per minimizzare questa caldaia, ma comunque è assegnata! Quindi, come andare su questo: Considera che C++ è il tuo intermediario, i tuoi oggetti sono in realtà oggetti C++! Bene che tu lo sappia adesso. Scrivi il tuo oggetto come se il tuo programma fosse in cpp not java, con i dati a cui vuoi accedere da entrambi i mondi. Quindi puoi usare il generatore di wrapper chiamato swig (http://www.swig.org/Doc1.3/Java.html) per renderlo accessibile a java e compilare una dll che tu chiami System.load (nome della DLL qui) in java. Prima fai questo, poi passa alla parte difficile! Per arrivare a python è necessario incorporare un interprete. In primo luogo suggerisco di fare alcuni programmi di hello interprete o questo tutorial . Una volta che hai funzionato, è tempo di far ballare il cavallo e la scimmia! Puoi inviare oggetti C++ a python tramite [boost] [3]. So che non ti ho dato il pesce, ti ho solo detto dove trovare il pesce. Alcuni indicatori da notare per questo durante la compilazione.

Quando si compila boost è necessario compilare una libreria condivisa. E devi includere e collegare al materiale di cui hai bisogno da jdk, cioè jawt.lib, jvm.lib, (avrai anche bisogno del client jvm.dll nel tuo percorso quando avvii l'applicazione) Oltre al python27.lib o qualunque e il boost_python-vc100-mt-1_55.lib. Quindi includi Python/include, jdk/include, enfatizza e usa solo le librerie condivise (dlls) altrimenti boost ha un lacrime. E sì pieno, lo so. Ci sono tanti modi in cui questo può diventare aspro. Quindi assicurati di fare ogni cosa un blocco dopo l'altro. Quindi mettili insieme.

+2

Qui una libreria che consente di scrivere gli script Python una volta e decidere quale metodo di integrazione (Jython, CPython tramite Jep e Py4j) utilizzare in runtime: https://github.com/subes/invesdwin-context-python Poiché ogni metodo ha i suoi vantaggi/svantaggi – subes

+0

@subisce che il progetto sembra fantastico l'ho scritto qualche tempo fa. Ti incoraggio a scrivere una risposta che vorrei invogliare. Non mi piace la risposta più alta haha ​​perché non penso che fornisca molte informazioni utili al di fuori di una ricerca su google. – Snickers3192

+0

Ho creato una risposta separata – subes

1

Jython ha alcune limitazioni:

There are a number of differences. First, Jython programs cannot use CPython extension modules written in C. These modules usually have files with the extension .so, .pyd or .dll. If you want to use such a module, you should look for an equivalent written in pure Python or Java. Although it is technically feasible to support such extensions - IronPython does so - there are no plans to do so in Jython.

Distributing my Python scripts as JAR files with Jython?

si può semplicemente chiamare script python (o bash o script Perl) da Java utilizzando Runtime o ProcessBuilder e passare uscita posteriore a Java:

Running a bash shell script in java

Running Command Line in Java

java runtime.getruntime() getting output from executing a command line program

0

Non è intelligente avere il codice Python all'interno di Java. Avvolgi il tuo codice Python con un pallone o un altro framework web per trasformarlo in un microservizio. Rendi il tuo programma java in grado di chiamare questo microservice (ad esempio tramite REST).

Credetemi, questo è molto semplice e vi farà risparmiare tonnellate di problemi. E i codici sono accoppiati liberamente in modo da renderli scalabili.

3

Diverse delle risposte indicano che è possibile utilizzare JNI o ​​JNA per accedere a cpthon ma non è consigliabile iniziare da zero perché esistono già librerie open source per l'accesso a cpython da java. Per esempio:

2

Ecco una libreria che permette di scrivere i vostri script Python una volta e decidere quale metodo di integrazione (Jython, CPython/PyPy via Jep e Py4j) da usare a runtime:

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

Poiché ogni metodo ha i suoi vantaggi/svantaggi come spiegato nel link.

+0

Progetto davvero interessante. – Snickers3192