Wywoływanie Pythona w Javie?

Zastanawiam się, czy jest możliwe wywoływanie funkcji Pythona z kodu Javy za pomocą jythona, czy tylko do wywoływania kodu Javy z Pythona?

Author: Chris Seymour, 2012-01-17

11 answers

Jython: Python dla platformy Java- http://www.jython.org/index.html

Możesz łatwo wywoływać funkcje Pythona z kodu Javy za pomocą Jython. To tak długo, jak Twój kod Pythona działa pod Jython, tzn. nie używa niektórych rozszerzeń c, które nie są obsługiwane.

Jeśli to działa dla Ciebie, jest to z pewnością najprostsze rozwiązanie, jakie możesz uzyskać. W przeciwnym razie możesz użyć org.python.util.PythonInterpreter z nowej obsługi interpretera Java6.

Prosty przykład z czubka mojej głowy-ale powinno działać mam nadzieję: (brak sprawdzania błędów dla zwięzłości)

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);
 101
Author: Voo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-08 12:59:55

Hej myślałem, że podam odpowiedź na to pytanie, mimo że jest późno. Myślę, że jest kilka ważnych rzeczy, które należy najpierw rozważyć, jak silne chcesz mieć powiązanie między Javą i Pythonem.

Po pierwsze Czy chcesz wywoływać tylko funkcje, Czy chcesz, aby Kod Pythona zmieniał dane w obiektach java? To bardzo ważne. Jeśli chcesz wywołać kod Pythona tylko z argumentami lub bez nich, to nie jest to zbyt trudne. Jeśli twoje argumenty są prymitywy to sprawia, że jeszcze łatwiej. Jeśli jednak chcesz, aby Klasa java implementowała w Pythonie funkcje Członkowskie, które zmieniają dane obiektu java, to nie jest to takie proste lub proste.

Po Drugie [4]} mówimy o cpythonie czy o jythonie? Powiedziałbym, że cpython jest tam, gdzie jest! Opowiadałbym się za tym, dlaczego python jest taki kool! Mając tak wysokie abstrakcje jednak dostęp do c, c++ w razie potrzeby. Wyobraź sobie, że możesz mieć to w Javie. To pytanie nie jest nawet warte pytanie, czy jython jest ok, bo to i tak jest łatwe.

Więc grałem następującymi metodami i wymieniłem je od łatwych do trudnych:

Java do Jython

zalety: trywialnie proste. Mieć rzeczywiste odniesienia do obiektów java

Wady: Brak CPython, Bardzo Wolno!

Jython z Javy jest tak prosty, a jeśli to naprawdę wystarczy, to świetnie. Jednak jest bardzo powolny i nie ma cpython! Czy warto żyć bez cpython I nie sądzę! Możesz łatwo mieć kod Pythona implementujący funkcje Członkowskie dla obiektów java.

Java to Jython to CPython via Pyro

Pyro jest zdalnym modułem obiektowym dla Pythona. Masz jakiś obiekt w interpreterze cpython i możesz wysyłać do niego obiekty, które są przesyłane przez serializację i może on również zwracać obiekty za pomocą tej metody. Zauważ, że jeśli wyślesz serializowany obiekt Pythona z jython, a następnie wywołasz niektóre funkcje, które zmieniają dane w jego członków, wtedy nie zobaczysz tych zmian w Javie. Musisz tylko pamiętać, aby odesłać dane, które chcesz od pyro. Uważam, że jest to najprostszy sposób, aby dostać się do cpython! Nie potrzebujesz żadnego jni lub jna lub swig lub .... Nie musisz znać żadnego c, ani c++. kool huh?

zalety: dostęp do cpython, nie tak trudny jak następujące metody

wady: nie można zmienić danych składowych obiektów java bezpośrednio z Pythona. Jest nieco pośredni, (jython jest środkowym człowiekiem).

Java do C / C++ przez JNI / JNA / SWIG do Pythona przez wbudowany interpreter (może używając bibliotek BOOST?)

OMG ta metoda nie jest dla osób o słabym sercu. I mogę powiedzieć, że zajęło mi bardzo dużo czasu, aby osiągnąć to przyzwoitą metodą. Głównym powodem, dla którego chciałbyś to zrobić, jest to, że możesz uruchomić kod cpython, który jako pełny nad tobą obiekt java. Przed podjęciem decyzji o wypróbowaniu Javy (która jest jak szympans) z pytonem (który jest jak koń). Po pierwsze, jeśli rozwalisz tłumacza, który jest wyłączony dla Ciebie program! I nie każ mi zaczynać od kwestii współbieżności! Ponadto istnieje allot allot kotła, uważam, że znalazłem najlepszą konfigurację, aby zminimalizować ten kocioł, ale nadal jest allot! Więc jak to zrobić: Rozważ, że C++ jest Twoim pośrednikiem, twoje obiekty są w rzeczywistości obiektami c++! Dobrze, że to wiesz. Po prostu napisz swój obiekt tak jakby twój program był w cpp a nie w Javie, z danymi, do których chcesz uzyskać dostęp z obu światów. Następnie możesz użyć generatora wrapperów o nazwie swig (http://www.swig.org/Doc1.3/Java.html ), aby uczynić to dostępne dla Javy i skompilować bibliotekę dll, którą wywołujesz System.load (nazwa dll tutaj) w Javie. Najpierw zrób to, a potem przejdź do trudnej części! Aby dostać się do Pythona, musisz osadzić interpreter. Po pierwsze proponuję zrobić kilka programów hello interpreter lub ten tutorial osadzenie Pythona w C / C. Kiedy już to działa, czas, by koń i małpa zatańczyły! Możesz wysłać obiekt c++ do Pythona poprzez [boost][3] . Wiem, że nie dałem ci ryb, tylko powiedziałem, gdzie je znaleźć. Kilka wskazówek, które należy zwrócić na to uwagę podczas kompilacji.

Podczas kompilacji boost będziesz musiał skompilować bibliotekę współdzieloną. I musisz dołączyć i link do rzeczy, których potrzebujesz od jdk, czyli jawt.lib, jvm.lib, (potrzebny będzie również klient jvm.dll w ścieżce podczas uruchamiania aplikacji), a także pyton27lib czy cokolwiek i boost_python-vc100-mt-1_55.lib. Następnie dołącz Python / include, jdk / include, boost i używaj tylko bibliotek współdzielonych (DLL), w przeciwnym razie boost ma łzy. I tak, wiem. Jest tak wiele sposobów, w które może to być kwaśne. Więc upewnij się, że wykonasz każdą rzecz blok po bloku. Więc złóż je razem.

 66
Author: Derrops,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Nie jest mądrze mieć kod Pythona w Javie. Zawiń kod Pythona za pomocą flask lub innego frameworka internetowego, aby stał się mikrousługą. Spraw, aby twój program java mógł wywołać tę mikrousługę (np. poprzez REST).

Uwierz mi, jest to o wiele proste i zaoszczędzi Ci mnóstwo problemów. A kody są luźno połączone, więc są skalowalne.

[[0]}Zaktualizowano 24 marca 2020: Zgodnie z komentarzem @stx, powyższe podejście nie nadaje się do masowego przesyłania danych między Klientem a serwerem. Oto inne podejście, które poleciłem: Łączenie Pythona i Javy z Rustem (c / c++ również ok). https://medium.com/@shmulikamar/https-medium-com-shmulikamar-connecting-python-and-java-with-rust-11c256a1dfb0
 18
Author: Peiming Hu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-24 05:41:18

Kilka odpowiedzi mówi, że można używać JNI lub JNA, aby uzyskać dostęp do cpythona, ale nie polecam zaczynać od zera, ponieważ istnieją już biblioteki open source do uzyskiwania dostępu do cpythona z Javy. Na przykład:

 10
Author: bsteffen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-16 20:48:30

Tutaj biblioteka, która pozwala pisać skrypty Pythona raz i zdecydować, którą metodę integracji (Jython, CPython/PyPy poprzez JEP i Py4j) użyć w czasie wykonywania:

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

Ponieważ każda metoda ma swoje zalety/wady, jak wyjaśniono w linku.

 8
Author: subes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-10 11:38:45

To zależy co rozumiesz przez funkcje Pythona? jeśli zostały napisane w cpython nie możesz ich bezpośrednio wywołać, będziesz musiał użyć JNI, ale jeśli zostały napisane w Jython możesz łatwo wywołać je z Javy, ponieważ Jython ostatecznie generuje kod bajtowy Javy.

Teraz Kiedy mówię napisany w cpython lub jython to nie ma większego sensu bo python to python i większość kodu będzie działać na obu implementacjach chyba że używasz konkretnych bibliotek które opiera się na cpython lub java.

Zobacz tutaj Jak używać interpretera Pythona w Javie.

 6
Author: Anurag Uniyal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-17 17:35:08

Możesz wywołać dowolny język z Javy za pomocą Java Native Interface

 5
Author: nidhin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-17 17:17:49

W zależności od twoich wymagań przydatne mogą być opcje takie jak XML-RPC, które mogą być używane do zdalnego wywoływania funkcji praktycznie w dowolnym języku obsługującym protokół.

 5
Author: Timo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-06 12:25:44

GraalVM to dobry wybór. Zrobiłem kombinację Java + Javascript z GraalVM do projektowania mikrousług (Java z odbiciem Javascript). Niedawno dodali wsparcie dla Pythona, dałbym mu szansę zwłaszcza z tym, jak duża jego społeczność rozrosła się na przestrzeni lat.

 5
Author: Wildhammer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-19 14:11:37

Jython ma pewne ograniczenia:

Istnieje wiele różnic. Po pierwsze, programy Jython nie mogą używać CPython moduły rozszerzeń napisane w C. moduły te zazwyczaj posiadają pliki z przedłużenie .pyd lub .dll. Jeśli chcesz skorzystać z takiego modułu, powinieneś zajrzeć dla odpowiednika napisanego w czystym Pythonie lub Javie. Chociaż technicznie jest możliwe do obsługi takich rozszerzeń - IronPython tak robi - nie ma planów aby to zrobić w Jython.

Dystrybuowanie skryptów Pythona jako plików JAR za pomocą Jython?

Możesz po prostu wywołać Skrypty Pythona (lub skrypty bash lub Perl) z Javy za pomocą Runtime lub ProcessBuilder i przekazać wyjście z powrotem do Javy:

Uruchamianie skryptu powłoki bash w Javie

Uruchamianie wiersza poleceń w Javie

Java runtime.getruntime () uzyskanie wyjścia z wykonania programu linii poleceń

 3
Author: alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:27

To daje całkiem dobry przegląd aktualnych opcji. Niektóre z nich są wymienione w innych odpowiedziach. Jython nie jest użyteczny, dopóki nie zdecydują się zaimplementować Pythona 3.x i wiele innych projektów nadchodzi od strony Pythona i chcą uzyskać dostęp do Javy. Ale jest jeszcze kilka opcji, aby nazwać coś, co nie zostało jeszcze nazwane: gRPC

 0
Author: garyee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-29 09:30:53