124 votes

Appeler Python en Java ?

Je me demande s'il est possible d'appeler des fonctions Python à partir d'un code Java en utilisant Jython, ou est-ce seulement pour appeler un code Java à partir de Python ?

4 votes

Veuillez consulter la question similaire et lire la réponse. bytes.com/topic/python/answers/

105voto

Voo Points 11981

Jython : Python pour la plate-forme Java - http://www.jython.org/index.html

Avec Jython, vous pouvez facilement appeler des fonctions python à partir de code Java. Pour autant que votre code python lui-même fonctionne sous Jython, c'est-à-dire qu'il n'utilise pas d'extensions c qui ne sont pas prises en charge.

Si cela fonctionne pour vous, c'est certainement la solution la plus simple qui soit. Sinon, vous pouvez utiliser org.python.util.PythonInterpreter du nouveau support de l'interpréteur Java6.

Un exemple simple, sorti de ma tête, mais qui devrait fonctionner, je l'espère : (aucune vérification des erreurs n'a été effectuée pour des raisons de brièveté).

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

À partir de 2021, Jython ne prend pas en charge Python 3.x.

0 votes

J'ai installé JYthon, ou je suppose que je l'ai fait, et je continue à essayer d'exécuter le code que vous avez décrit, mais il est mis en évidence comme une erreur. L'installation de Jython doit-elle se faire dans un dossier spécifique, soit dans le dossier python, soit dans le dossier java ?

2 votes

Il n'y a pas d'erreur, j'ai juste du mal à intégrer Jython dans Netbeans.

0 votes

S'il n'y avait pas d'erreur, cela fonctionnerait, donc ce n'est manifestement pas le cas ;) "Erreur" ne signifie pas erreur d'exécution, il peut aussi s'agir d'une erreur de compilation.

71voto

Snickers3192 Points 2219

Je pense qu'il y a des choses importantes à prendre en compte en premier lieu pour déterminer la force du lien entre Java et Python.

Tout d'abord Voulez-vous seulement appeler des fonctions ou voulez-vous réellement que du code python modifie les données de vos objets java ? Cette question est très importante. Si vous voulez seulement appeler du code python avec ou sans arguments, ce n'est pas très difficile. Si vos arguments sont des primitives, c'est encore plus facile. Cependant, si vous voulez que la classe java implémente des fonctions membres en python, qui modifient les données de l'objet java, ce n'est pas si facile ou direct.

Ensuite, parlons-nous de cpython ou de jython ? Je dirais que cpython est là où il faut ! Je dirais que c'est la raison pour laquelle Python est si cool ! Avoir des abstractions aussi élevées, mais avoir accès à c, c++ quand on en a besoin. Imaginez si vous pouviez avoir cela en java. Cette question ne vaut même pas la peine d'être posée si jython est ok parce qu'alors c'est facile de toute façon.

J'ai donc joué avec les méthodes suivantes, et je les ai classées de faciles à difficiles :

De Java à Jython

Avantages : Trivialement facile. Avoir des références réelles aux objets java

Inconvénients : Pas de CPython, extrêmement lent !

Jython à partir de java est si facile, et si cela suffit vraiment, alors tant mieux. Cependant, il est très lent et il n'y a pas de cpython ! La vie vaut-elle la peine d'être vécue sans cpython ? Je ne le pense pas ! Vous pouvez facilement avoir du code python implémentant vos fonctions membres pour vos objets java.

De Java à Jython à CPython via Pyro

Pyro est le module d'objets distants pour python. Vous avez un objet sur un interpréteur cpython, et vous pouvez lui envoyer des objets qui sont transférés via la sérialisation et il peut aussi retourner des objets via cette méthode. Notez que si vous envoyez un objet python sérialisé depuis jython et que vous appelez ensuite des fonctions qui modifient les données de ses membres, vous ne verrez pas ces modifications dans java. Vous devez simplement vous rappeler de renvoyer les données que vous voulez de pyro. Je pense que c'est le moyen le plus simple d'accéder à cpython ! Vous n'avez pas besoin de jni, jna, swig ou ..... Vous n'avez pas besoin de connaître le c, ou le c++. super hein ?

Avantages : Accès à cpython, pas aussi difficile que les méthodes suivantes

Inconvénients : Impossible de modifier les données membres des objets java directement depuis python. C'est plutôt indirect, (jython est un intermédiaire).

Java vers C/C++ via JNI/JNA/SWIG vers Python via un interpréteur embarqué (peut-être en utilisant les bibliothèques BOOST ?)

OMG, cette méthode n'est pas pour les âmes sensibles. Et je peux vous dire qu'il m'a fallu beaucoup de temps pour y parvenir avec une méthode décente. La raison principale pour laquelle vous voulez faire cela est que vous pouvez exécuter du code cpython qui a un contrôle total sur votre objet java. Il y a des choses importantes à prendre en compte avant de décider d'essayer de panifier java (qui est comme un chimpanzé) avec python (qui est comme un cheval). Tout d'abord, si vous plantez l'interpréteur, c'est l'extinction des feux pour votre programme ! Et ne me lancez pas sur les problèmes de concurrence ! En outre, il y a beaucoup de chaudière, je crois que j'ai trouvé la meilleure configuration pour minimiser cette chaudière mais c'est quand même beaucoup ! Alors comment faire : Considérez que le C++ est votre intermédiaire, vos objets sont en fait des objets C++ ! C'est bien que vous le sachiez maintenant. Ecrivez simplement votre objet comme si votre programme était en cpp et non en java, avec les données auxquelles vous voulez accéder depuis les deux mondes. Ensuite, vous pouvez utiliser le générateur de wrapper appelé swig ( http://www.swig.org/Doc1.3/Java.html ) pour le rendre accessible à java et compiler une dll que vous appelez System.load(nom de la dll ici) en java. Commencez par faire fonctionner tout cela, puis passez à la partie la plus difficile ! Pour accéder à Python, vous devez intégrer un interpréteur. Tout d'abord, je vous suggère de faire quelques programmes d'interprétation de type hello ou de suivre ce tutoriel. Intégrer python dans C/C . Une fois que cela fonctionne, il est temps de faire danser le cheval et le singe ! Vous pouvez envoyer votre objet c++ à python via [boost][3] . Je sais que je ne vous ai pas donné le poisson, je vous ai simplement dit où trouver le poisson. Quelques points à noter lors de la compilation.

Lorsque vous compilez boost, vous devez compiler une bibliothèque partagée. Et vous devez inclure et lier les éléments dont vous avez besoin de jdk, c'est-à-dire jawt.lib, jvm.lib, (vous aurez également besoin du client jvm.dll dans votre chemin lors du lancement de l'application) ainsi que python27.lib ou autre et boost_python-vc100-mt-1_55.lib. Ensuite, incluez Python/include, jdk/include, boost et n'utilisez que des librairies partagées (dlls) sinon boost a la larme à l'oeil. Et oui, je sais. Il y a tellement de façons dont cela peut tourner au vinaigre. Donc assurez-vous de faire chaque chose bloc par bloc. Puis mettez-les ensemble.

23voto

Peiming Hu Points 407

Ce n'est pas intelligent d'avoir du code python dans java. Enveloppez votre code python avec flask ou un autre framework web pour en faire un microservice. Cela permet à votre programme java d'appeler ce microservice (par exemple via REST).

Cette approche est simple et elle vous épargnera des tas de problèmes. De plus, les codes sont faiblement couplés et sont donc évolutifs.

Mis à jour le 24 mars 2020 : Selon le commentaire de @stx, l'approche ci-dessus n'est pas adaptée au transfert massif de données entre le client et le serveur. Voici une autre approche que je recommande : Connecter Python et Java avec Rust(C/C++ aussi ok). https://medium.com/@shmulikamar/https-medium-com-shmulikamar-connexion-python-et-java-with-rust-11c256a1dfb0

11voto

bsteffen Points 221

Plusieurs réponses mentionnent que vous pouvez utiliser JNI ou JNA pour accéder à cpython mais je ne recommande pas de partir de zéro car il existe déjà des bibliothèques open source pour accéder à cpython depuis java. Par exemple :

9voto

Wildhammer Points 132

GraalVM est un bon choix. J'ai fait une combinaison Java+Javascript avec GraalVM pour la conception de microservices (Java avec réflexion Javascript). Ils ont récemment ajouté le support de python, je l'essaierais, surtout avec la croissance de sa communauté au fil des ans.

MISE À JOUR juin 2021

https://www.graalvm.org/reference-manual/python/ dit

GraalVM fournit un runtime conforme à Python 3.8. L'un des principaux objectifs du runtime Python de GraalVM est de prendre en charge SciPy et les bibliothèques qui le composent, ainsi que de travailler avec d'autres bibliothèques de science des données et d'apprentissage automatique issues du riche écosystème Python. À ce stade, le runtime Python est mis à la disposition des expérimentateurs et des utilisateurs finaux curieux.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X