Виклик Python на Java?


117

Мені цікаво, чи можна викликати функції python з коду Java за допомогою jython, чи це лише для виклику коду Java з python?


3
Будь ласка, подивіться на подібне запитання та прочитайте відповідь. bytes.com/topic/python/answers/…
AlexR

Відповіді:


101

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

Я встановив JYthon, або я припускаю, що я це зробив, і я намагаюся запустити код, який ви окреслили, але він виділився як помилка. Чи потрібно вкладку Jython переходити до певної папки - у папках python або java?
Шахаб

2
Немає жодної помилки, мені просто важко інтегрувати Jython в Netbeans
Shahab

Якщо немає помилки, вона б працювала, тому, очевидно, це не так;) "Помилка" не означає помилку виконання, може бути помилкою компіляції.
Во

Моє погано, це було погане використання слова. Я намагався додати jython.jar до свого проекту та netbeans. Я зрозумів це, хоча
Шахаб

1
Кінець життя Python 2 становить 1.1.2020, а Jython підтримує лише Python 2.7. тому жоден Jython в основному не мертвий. Найкращий варіант (найпростіший) варіант
ліга

63

Гей, я думав, що я введу свою відповідь на це, хоча це вже пізно. Я думаю, що слід спочатку розглянути кілька важливих речей із тим, наскільки сильно ви хочете мати зв’язок між 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 має сліз. І так, я знаю. Існує так багато способів, як це може киснути. Тому переконайтеся, що ви робите кожну річ по блоку. Потім складіть їх разом.


2
Тут розміщена бібліотека, яка дає змогу один раз написати свої сценарії python та вирішити, який метод інтеграції (Jython, CPython через Jep та Py4j) використовувати під час виконання: github.com/subes/invesdwin-context-python Оскільки кожен метод має свої переваги / недоліки
підпорядковується

@subes, що проект виглядає приголомшливо, я писав це деякий час тому. Я закликаю вас написати відповідь, яку я б схвалив. Я не люблю верхню відповідь ха-ха, тому що я не думаю, що вона надає багато корисної інформації поза пошуковим запитом Google.
Snickers3192

Я створив окрему відповідь
subes

3
чи пахне ця відповідь на "це має бути прийнята відповідь" чи це тільки я? ;-)
Маурісіо Грація Гутьєррес

18

Нерозумно мати код 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


+1, а як щодо додаткової продуктивності та комунікаційних витрат на створення та аналіз повідомлень на обох кінцях?
stx

так, для цього потрібно визначити інтерфейс api з мінімальним необхідним входом / виходом. Не розумно мати багато передавачів даних між клієнтом / сервером у мережі. Якщо ви не можете визначити такий інтерфейс, такий підхід до дизайну не підходить.
Пейм Хуа

10

У деяких відповідях згадується, що ви можете використовувати JNI або JNA для доступу до cpython, але я б не рекомендував починати з нуля, оскільки вже є бібліотеки з відкритим кодом для доступу до cpython з Java. Наприклад:


8

Тут розміщена бібліотека, яка дозволяє вам один раз писати сценарії python і визначати, який метод інтеграції (Jython, CPython / PyPy через Jep і Py4j) використовувати під час виконання:

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

Оскільки кожен метод має свої переваги / недоліки, як пояснено у посиланні.


Цей проект не має жодної версії.
Крістіан

@ChristianSchlichtherle invesdwin-context-python версія 1.0.0 недоступна; завдяки цьому маленькому самоцвіту: github.com/loewenfels/dep-graph-releaser
subes

6

Це залежить від того, що ви розумієте під функціями python? якщо вони були написані на cpython, ви не можете їх безпосередньо зателефонувати, вам доведеться використовувати JNI , але якщо вони були написані на Jython, ви можете легко зателефонувати їм з Java, оскільки jython врешті-решт генерує байт-код Java.

Тепер, коли я кажу, що написано на cpython або jython, це не має особливого сенсу, тому що python - це python, і більшість кодів працюватиме в обох реалізаціях, якщо ви не використовуєте конкретні бібліотеки, які покладаються на cpython або java.

дивіться тут, як використовувати інтерпретатор Python на Java.


5

Залежно від ваших вимог, такі параметри, як XML-RPC, можуть бути корисними, які можна використовувати для віддаленого виклику функцій практично будь-якою мовою, що підтримує протокол.


5

GraalVM - хороший вибір. Я робив комбінацію Java + Javascript з GraalVM для дизайну мікросервісів (Java з відображенням Javascript). Нещодавно вони додали підтримку python, і я б спробував це особливо, наскільки великою стала його спільнота за ці роки.


4

Ви можете зателефонувати на будь-яку мову з Java за допомогою Java Native Interface


6
Будь-яку мову, що сама по собі можна назвати з c, що є. Ну добре, python може, але Jython є набагато простішим рішенням насправді (або з використанням PyInterpreter в j6 +). Не так банально писати код для виклику функцій python з c.
Voo

2

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 (), отримуючи висновок від виконання програми командного рядка


0

Це дає досить хороший огляд поточних варіантів. Деякі з них названі в інших відповідях. Jython не використовується, поки вони не вирішать реалізувати Python 3.x, і багато інших проектів надходять з боку python і хочуть отримати доступ до Java. Але є ще кілька варіантів, щоб назвати те, що ще не було названо: gRPC

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.