Відповіді:
Jython: Python для платформи Java - http://www.jython.org/index.html
Ви можете легко викликати функції python з коду Java за допомогою Jython. Це означає, що ваш код python сам працює під jython, тобто не використовує деякі c-розширення, які не підтримуються.
Якщо це працює для вас, це, безумовно, найпростіше рішення, яке ви можете отримати. В іншому випадку ви можете скористатися org.python.util.PythonInterpreter
новою підтримкою інтерпретатора Java6.
Простий приклад з верхньої частини голови - але я повинен працювати, я сподіваюся: (перевірка помилок не робиться для стислості)
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);
Гей, я думав, що я введу свою відповідь на це, хоча це вже пізно. Я думаю, що слід спочатку розглянути кілька важливих речей із тим, наскільки сильно ви хочете мати зв’язок між java та python.
По-перше, ви хочете лише викликати функції або дійсно хочете, щоб код python міняв дані у ваших об'єктах Java? Це дуже важливо. Якщо ви хочете лише зателефонувати на якийсь код python з аргументами або без них, це не дуже складно. Якщо ваші аргументи примітивні, це робить це ще простіше. Однак якщо ви хочете, щоб клас java реалізував функції члена в python, які змінюють дані об'єкта java, то це не так просто чи прямо вперед.
По-друге , ми говоримо cpython чи зробимо jython? Я б сказав, що тут знаходиться cpython! Я б прихильник цього, тому пітон такий кул! Маючи такі високі абстракції, однак доступ до c, c ++ при необхідності. Уявіть, якби у вас це було в Java. Це питання навіть не варто запитувати, чи добре у jython, тому що це все одно просто.
Тому я грав із такими методами і перераховував їх від легких до складних:
Ява в Jython
Переваги: Тривіально просто. Мати фактичні посилання на об’єкти java
Недоліки: немає CPython, надзвичайно повільно!
Jython з Java дуже легкий, і якщо цього справді достатньо, то чудово. Однак це дуже повільно і немає копійфона! Чи варто життя жити без кептона, я так не думаю! Ви можете легко мати код python, що реалізує функції вашого члена для вас об'єктів java.
Java в Jython в CPython через Pyro
Pyro - це віддалений об'єктний модуль для python. У вас є певний об'єкт у інтерпретаторі cpython, і ви можете надсилати йому об'єкти, які передаються через серіалізацію, і він також може повертати об'єкти за допомогою цього методу. Зауважте, що якщо ви надішліть серійний об’єкт python від jython, а потім зателефонуєте до деяких функцій, які змінюють дані його членів, ви не побачите цих змін у java. Вам просто потрібно пам’ятати, щоб надіслати назад дані, які ви хочете від pyro. Це я вважаю, це найпростіший спосіб дістатися до cpython! Вам не потрібно ні jni, ні jna, ні swig, ні .... Вам не потрібно знати жодного c, або c ++. kool так?
Переваги: доступ до cpython не такий складний, як наступні методи
Недоліки: Неможливо змінити дані про об'єкти java безпосередньо з python. Дещо опосередкований, (jython - середня людина).
Java до C / C ++ через JNI / JNA / SWIG до Python через вбудований інтерпретатор (можливо, використовуючи BOOST Бібліотеки?)
OMG цей метод не для слабкого серця. І я можу вам сказати, що мені потрібно було дуже багато часу, щоб досягти цього гідним методом. Основна причина, яку ви хочете зробити це, полягає в тому, що ви можете запустити код cpython, який як повноцінна поверхня над вашим об'єктом Java. Перш ніж вирішити спробувати хліб з джавою (що схоже на шимпанзе) з пітоном (що схоже на коня), слід розглянути основні основні речі. По-перше, якщо ви зламаєте перекладача, який загоряється для вашої програми! І не запускайте мене з питань одночасності! Крім того, є багато виділення котла, я вважаю, що я знайшов найкращу конфігурацію, щоб мінімізувати цей котел, але все-таки це багато! Тож як зробити це: Подумайте, що C ++ - це ваша середня людина, а ваші об’єкти - це фактично c ++ об’єкти! Добре, що ви це зараз знаєте. Просто напишіть об’єкт так, ніби ваша програма, як у cpp, а не java, з даними, до яких потрібно отримати доступ з обох світів. Тоді ви можете використовувати генератор обгортки під назвою swig (http://www.swig.org/Doc1.3/Java.html ), щоб зробити це доступним для Java та скласти dll, який ви називаєте System.load (назва тут dll) у Java. Почніть спочатку цю роботу, а потім перейдіть до важкої частини! Щоб потрапити на python, вам потрібно вбудувати інтерпретатора. Під - перше , я пропоную робити деякі програми інтерпретатора привіт або це підручник Вбудовування пітона в C / C . Як тільки ви працюєте, прийшов час змусити коня та мавпи танцювати! Ви можете відправити вам об’єкт c ++ на python через [boost] [3]. Я знаю, що я не дав тобі рибу, просто сказав тобі, де знайти рибу. Деякі вказівки слід зазначити на це при складанні.
Коли ви компілюєте прискорення, вам потрібно буде скласти спільну бібліотеку. І вам потрібно включити і посилання на потрібні вам речі від jdk, тобто jawt.lib, jvm.lib, (вам також знадобиться клієнт jvm.dll у вашому шляху під час запуску програми), а також python27.lib або будь-що і boost_python-vc100-mt-1_55.lib. Потім включайте Python / include, jdk / include, збільшуйте та використовуйте лише спільні бібліотеки (dlls), інакше boost має сліз. І так, я знаю. Існує так багато способів, як це може киснути. Тому переконайтеся, що ви робите кожну річ по блоку. Потім складіть їх разом.
Нерозумно мати код python всередині Java. Оберніть ваш пітон-код фляжкою чи іншою веб-рамкою, щоб зробити його мікропрограмою. Зробіть свою програму java можливою зателефонувати в цю мікросервіс (наприклад, через REST).
Зверніть мене, це дуже просто і допоможе вам заощадити багато питань. І коди нещільно пов'язані, тому вони є масштабованими.
Оновлено 24 березня 2020 року: Відповідно до коментаря @ stx, зазначений вище підхід не підходить для масової передачі даних між клієнтом та сервером. Ось ще один підхід, який я рекомендував: Підключення Python та Java з Rust (C / C ++ також нормально). https://medium.com/@shmulikamar/https-medium-com-shmulikamar-connecting-python-and-java-with-rust-11c256a1dfb0
Тут розміщена бібліотека, яка дозволяє вам один раз писати сценарії python і визначати, який метод інтеграції (Jython, CPython / PyPy через Jep і Py4j) використовувати під час виконання:
https://github.com/subes/invesdwin-context-python
Оскільки кожен метод має свої переваги / недоліки, як пояснено у посиланні.
Це залежить від того, що ви розумієте під функціями python? якщо вони були написані на cpython, ви не можете їх безпосередньо зателефонувати, вам доведеться використовувати JNI , але якщо вони були написані на Jython, ви можете легко зателефонувати їм з Java, оскільки jython врешті-решт генерує байт-код Java.
Тепер, коли я кажу, що написано на cpython або jython, це не має особливого сенсу, тому що python - це python, і більшість кодів працюватиме в обох реалізаціях, якщо ви не використовуєте конкретні бібліотеки, які покладаються на cpython або java.
дивіться тут, як використовувати інтерпретатор Python на Java.
GraalVM - хороший вибір. Я робив комбінацію Java + Javascript з GraalVM для дизайну мікросервісів (Java з відображенням Javascript). Нещодавно вони додали підтримку python, і я б спробував це особливо, наскільки великою стала його спільнота за ці роки.
Ви можете зателефонувати на будь-яку мову з Java за допомогою Java Native Interface
Jython має деякі обмеження:
Існує ряд відмінностей. По-перше, програми Jython не можуть використовувати модулі розширення CPython, написані на C. Ці модулі зазвичай мають файли з розширенням .so, .pyd або .dll. Якщо ви хочете використовувати такий модуль, вам слід шукати еквівалент, написаний на чистому Python або Java. Хоча технічно реально підтримувати такі розширення - IronPython робить це - у Jython не планується.
Поширювати мої сценарії Python як JAR-файли за допомогою Jython?
Ви можете просто викликати сценарії python (або bash або Perl-скрипти) з Java за допомогою Runtime або ProcessBuilder і повернути вихід назад на Java:
Запуск сценарію bash shell в Java
Запуск командного рядка в Java
java runtime.getruntime (), отримуючи висновок від виконання програми командного рядка
Це дає досить хороший огляд поточних варіантів. Деякі з них названі в інших відповідях. Jython не використовується, поки вони не вирішать реалізувати Python 3.x, і багато інших проектів надходять з боку python і хочуть отримати доступ до Java. Але є ще кілька варіантів, щоб назвати те, що ще не було названо: gRPC