Możesz łatwo wywoływać funkcje Pythona z kodu Java za pomocą Jythona. To jest tak długo, jak sam kod Pythona działa pod jythonem, tj. Nie używa niektórych rozszerzeń c, które nie są obsługiwane.
Jeśli to działa, z pewnością jest to najprostsze rozwiązanie, jakie możesz uzyskać. W przeciwnym razie możesz skorzystać org.python.util.PythonInterpreterz nowej obsługi interpretera Java6.
Prosty przykład z góry mojej głowy - ale mam nadzieję, że powinien zadziałać: (brak sprawdzania błędów dla zwięzłości)
PythonInterpreter interpreter =newPythonInterpreter();
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 stringPyObject someFunc = interpreter.get("funcName");PyObject result = someFunc.__call__(newPyString("Test!"));String realResult =(String) result.__tojava__(String.class);
Zainstalowałem JYthon lub zakładam, że tak, i nadal próbuję uruchomić kod, który nakreśliłeś, ale został on wyróżniony jako błąd. Czy instalacja Jythona musi przejść do określonego folderu, czy to w folderze python, czy java?
Shahab
2
Nie ma żadnego błędu, po prostu mam trudności z integracją Jythona z Netbeans
Shahab,
Jeśli nie ma błędu, to zadziała, więc oczywiście tak nie jest;) „Błąd” nie oznacza błędu w czasie wykonywania, może to być również błąd kompilacji.
Voo
Moja wina, to było kiepskie użycie tego słowa. Próbowałem dodać jython.jar do mojego projektu i netbeans. Rozgryzłem to jednak
Shahab
1
Koniec życia Pythona 2 to 1.1.2020, a Jython obsługuje tylko Python 2.7. więc żaden Jython nie jest w zasadzie martwy. Najlepszą (najprostszą) opcją jest Jep lib
garyee
63
Hej, myślałem, że podam swoją odpowiedź, mimo że jest późno. Myślę, że jest kilka ważnych rzeczy, które należy najpierw rozważyć, a mianowicie, jak silne chcesz mieć połączenie między Javą a Pythonem.
Po pierwsze, czy chcesz tylko wywoływać funkcje, czy faktycznie chcesz, aby kod Pythona zmieniał dane w obiektach Java? To jest bardzo ważne. Jeśli chcesz tylko wywołać jakiś kod Pythona z argumentami lub bez, to nie jest to zbyt trudne. Jeśli twoje argumenty są prymitywne, będzie to jeszcze łatwiejsze. Jeśli jednak chcesz mieć funkcje składowe klasy java implementujące w Pythonie, które zmieniają dane obiektu java, to nie jest to takie łatwe ani proste.
Po drugie, czy mówimy o cpythonie, czy też zrobi to jython? Powiedziałbym, że cpython jest tam, gdzie jest! Opowiadałbym się za tym, dlaczego Python jest taki kool! Mając tak wysokie abstrakcje, jednak w razie potrzeby dostęp do c, c ++. Wyobraź sobie, że możesz to mieć w Javie. To pytanie nie jest nawet warte pytania, czy jython jest w porządku, ponieważ i tak jest to łatwe.
Więc bawiłem się następującymi metodami i wymieniłem je od łatwych do trudnych:
Java na Jython
Zalety: banalnie proste. Mają rzeczywiste odniesienia do obiektów Java
Wady: brak CPythona, bardzo wolno!
Jython z javy jest tak łatwy, a jeśli to naprawdę wystarczy, to świetnie. Jednak jest bardzo powolny i nie ma cpythonu! Czy warto żyć bez cpythona, nie sądzę! Możesz łatwo mieć kod Pythona implementujący funkcje składowe dla obiektów Java.
Java na Jython na CPython przez Pyro
Pyro to zdalny moduł obiektowy dla Pythona. Masz jakiś obiekt na interpretatorze cpython i możesz wysłać mu obiekty, które są przesyłane przez serializację, a także może zwracać obiekty za pomocą tej metody. Zwróć uwagę, że jeśli wyślesz zserializowany obiekt Pythona z jythona, a następnie wywołasz funkcje, które zmieniają dane w jego elementach członkowskich, nie zobaczysz tych zmian w java. Musisz tylko pamiętać o odesłaniu żądanych danych z pyro. Myślę, że to najłatwiejszy sposób, aby dostać się do cpython! Nie potrzebujesz żadnego jni, jna, swig lub ... Nie musisz znać żadnego c ani c ++. kool co?
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 pośrednikiem).
Java na C / C ++ przez JNI / JNA / SWIG do Pythona przez wbudowany interpreter (może przy użyciu bibliotek BOOST?)
OMG, ta metoda nie jest dla osób o słabym sercu. I mogę powiedzieć, że zajęło mi to bardzo dużo czasu, zanim udało mi się to osiągnąć przyzwoitą metodą. Głównym powodem, dla którego chciałbyś to zrobić, jest to, że możesz uruchomić kod cpython, który będzie miał pełną kontrolę nad obiektem Java. Przed podjęciem decyzji o spróbowaniu chleba java (który jest jak szympans) z pytonem (który jest jak koń), należy wziąć pod uwagę ważne kwestie. Po pierwsze, jeśli zawiesisz interpreter, który jest wyłączony dla twojego programu! I nie zaczynaj od kwestii współbieżności! Ponadto jest dużo kotła, wierzę, że znalazłem najlepszą konfigurację, aby zminimalizować ten kocioł, ale nadal jest! Jak więc się do tego zabrać: Weź pod uwagę, że C ++ jest twoim pośrednikiem, twoje obiekty to w rzeczywistości obiekty c ++! Dobrze, że już to wiesz. Po prostu napisz swój obiekt tak, jakby twój program był jak w cpp, a nie java, z danymi, do których chcesz uzyskać dostęp z obu światów. Następnie możesz użyć generatora opakowań o nazwie swig (http://www.swig.org/Doc1.3/Java.html ), aby udostępnić to java i skompilować bibliotekę dll, którą wywołujesz System.load (tutaj nazwa dll) w java. Najpierw zajmij się tym, a potem przejdź do najtrudniejszej części! Aby dostać się do Pythona, musisz osadzić interpreter. Po pierwsze proponuję robi kilka programów tłumacza hello czy ten samouczek Osadzanie Pythona w C / C . Kiedy już to zrobisz, pora zmusić konia i małpkę do tańca! Możesz wysłać obiekt C ++ do Pythona przez [boost] [3]. Wiem, że nie dałem ci ryby, powiedziałem tylko, gdzie ją znaleźć. Kilka wskazówek, na które należy zwrócić uwagę podczas kompilacji.
Podczas kompilacji przyspieszenia musisz skompilować bibliotekę współdzieloną. I musisz dołączyć i linkować do rzeczy, których potrzebujesz z jdk, tj. Jawt.lib, jvm.lib (będziesz również potrzebować klienta jvm.dll w swojej ścieżce podczas uruchamiania aplikacji), a także python27.lib lub 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 kłopoty. I tak, w pełni wiem. Jest tak wiele sposobów, w jakie może się to zepsuć. Więc upewnij się, że wykonujesz każdą rzecz blok po bloku. Następnie złóż je razem.
Tutaj biblioteka, która pozwala raz napisać skrypty Pythona i zdecydować, której metody integracji (Jython, CPython przez Jep i Py4j) użyć w czasie wykonywania: github.com/subes/invesdwin-context-python Ponieważ każda metoda ma swoje zalety / wady
subes
@subes, ten projekt wygląda niesamowicie Napisałem to jakiś czas temu. Zachęcam do napisania odpowiedzi, którą zagłosowałbym za. Nie podoba mi się haha najlepsza odpowiedź, ponieważ nie sądzę, aby zawierała wiele przydatnych informacji poza wyszukiwarką Google.
Snickers3192
Stworzyłem osobną odpowiedź
subes
3
czy ta odpowiedź pachnie "to powinna być akceptowana odpowiedź", czy to tylko ja? ;-)
Mauricio Gracia Gutierrez
18
Nie jest mądrze mieć kod Pythona w java. Zawiń swój kod w języku Python za pomocą platformy flask lub innej platformy internetowej, aby uczynić go mikrousługą. Spraw, aby Twój program java mógł wywoływać tę mikrousługę (np. Przez REST).
Uwierz mi, to jest o wiele proste i pozwoli Ci zaoszczędzić mnóstwo problemów. Kody są luźno powiązane, więc są skalowalne.
+1, ale co z dodatkową wydajnością i narzutem komunikacyjnym związanym z tworzeniem i analizowaniem wiadomości w obie strony na obu końcach?
stx
tak, to musi zdefiniować interfejs API z minimalnym wymaganym wejściem / wyjściem. Przesyłanie dużej ilości danych między klientem a serwerem w sieci nie jest rozsądne. Jeśli nie możesz zdefiniować takiego interfejsu, to podejście projektowe nie pasuje.
Peiming Hu
10
Kilka odpowiedzi wspomina, że możesz użyć JNI lub JNA, aby uzyskać dostęp do cpython, ale nie polecałbym zaczynać od zera, ponieważ istnieją już biblioteki open source umożliwiające dostęp do cpython z javy. Na przykład:
Tutaj biblioteka, która pozwala ci raz napisać skrypty Pythona i zdecydować, której metody integracji (Jython, CPython / PyPy przez Jep i Py4j) użyć w czasie wykonywania:
To zależy od tego, co masz na myśli przez funkcje Pythona? jeśli zostały napisane w cpythonie , nie możesz ich bezpośrednio wywołać, będziesz musiał użyć JNI , ale jeśli zostały napisane w Jythonie możesz je łatwo wywołać z javy, ponieważ jython ostatecznie generuje kod bajtowy java.
Teraz, kiedy mówię napisane w cpythonie lub jythonie, nie ma to większego sensu, ponieważ python to python i większość kodu będzie działać na obu implementacjach, chyba że używasz określonych bibliotek, które opierają się na cpythonie lub javie.
W zależności od wymagań przydatne mogą być opcje takie jak XML-RPC , które można wykorzystać do zdalnego wywoływania funkcji praktycznie w dowolnym języku obsługującym protokół.
GraalVM to dobry wybór. Zrobiłem połączenie Java + Javascript z GraalVM do projektowania mikrousług (Java z odzwierciedleniem Javascript). Niedawno dodali obsługę Pythona, spróbuję, szczególnie biorąc pod uwagę, jak duża stała się jego społeczność na przestrzeni lat.
Każdy język, który sam można nazwać z c to znaczy. No dobrze, Python może, ale Jython jest tam naprawdę znacznie prostszym rozwiązaniem (lub używając PyInterpreter w j6 +). Nie jest takie trywialne napisanie kodu wywołującego funkcje Pythona z c.
Voo
2
Jython ma pewne ograniczenia:
Istnieje wiele różnic. Po pierwsze, programy w języku Jython nie mogą używać modułów rozszerzających CPython napisanych w języku C. Moduły te zwykle mają pliki z rozszerzeniami .so, .pyd lub .dll. Jeśli chcesz skorzystać z takiego modułu, powinieneś poszukać odpowiednika napisanego w czystym Pythonie lub Javie. Chociaż obsługa takich rozszerzeń jest technicznie wykonalna - IronPython to robi - nie ma takich planów w Jythonie.
możesz po prostu wywołać skrypty Pythona (lub skrypty bash lub Perl) z języka Java za pomocą środowiska uruchomieniowego lub ProcessBuilder i przekazać dane wyjściowe z powrotem do języka Java:
To daje całkiem dobry przegląd ciągu bieżącej opcji. Niektóre z nich są wymienione w innych odpowiedziach. Jython nie nadaje się do użytku, dopóki nie zdecydują się na wdrożenie Pythona 3.x, a wiele innych projektów pochodzi ze strony Pythona i chce mieć dostęp do javy. Ale jest jeszcze kilka opcji, aby nazwać coś, co nie zostało jeszcze nazwane: gRPC
Odpowiedzi:
Jython: Python dla platformy Java - http://www.jython.org/index.html
Możesz łatwo wywoływać funkcje Pythona z kodu Java za pomocą Jythona. To jest tak długo, jak sam kod Pythona działa pod jythonem, tj. Nie używa niektórych rozszerzeń c, które nie są obsługiwane.
Jeśli to działa, z pewnością jest to najprostsze rozwiązanie, jakie możesz uzyskać. W przeciwnym razie możesz skorzystać
org.python.util.PythonInterpreter
z nowej obsługi interpretera Java6.Prosty przykład z góry mojej głowy - ale mam nadzieję, że powinien zadziałać: (brak sprawdzania błędów dla zwięzłości)
źródło
Hej, myślałem, że podam swoją odpowiedź, mimo że jest późno. Myślę, że jest kilka ważnych rzeczy, które należy najpierw rozważyć, a mianowicie, jak silne chcesz mieć połączenie między Javą a Pythonem.
Po pierwsze, czy chcesz tylko wywoływać funkcje, czy faktycznie chcesz, aby kod Pythona zmieniał dane w obiektach Java? To jest bardzo ważne. Jeśli chcesz tylko wywołać jakiś kod Pythona z argumentami lub bez, to nie jest to zbyt trudne. Jeśli twoje argumenty są prymitywne, będzie to jeszcze łatwiejsze. Jeśli jednak chcesz mieć funkcje składowe klasy java implementujące w Pythonie, które zmieniają dane obiektu java, to nie jest to takie łatwe ani proste.
Po drugie, czy mówimy o cpythonie, czy też zrobi to jython? Powiedziałbym, że cpython jest tam, gdzie jest! Opowiadałbym się za tym, dlaczego Python jest taki kool! Mając tak wysokie abstrakcje, jednak w razie potrzeby dostęp do c, c ++. Wyobraź sobie, że możesz to mieć w Javie. To pytanie nie jest nawet warte pytania, czy jython jest w porządku, ponieważ i tak jest to łatwe.
Więc bawiłem się następującymi metodami i wymieniłem je od łatwych do trudnych:
Java na Jython
Zalety: banalnie proste. Mają rzeczywiste odniesienia do obiektów Java
Wady: brak CPythona, bardzo wolno!
Jython z javy jest tak łatwy, a jeśli to naprawdę wystarczy, to świetnie. Jednak jest bardzo powolny i nie ma cpythonu! Czy warto żyć bez cpythona, nie sądzę! Możesz łatwo mieć kod Pythona implementujący funkcje składowe dla obiektów Java.
Java na Jython na CPython przez Pyro
Pyro to zdalny moduł obiektowy dla Pythona. Masz jakiś obiekt na interpretatorze cpython i możesz wysłać mu obiekty, które są przesyłane przez serializację, a także może zwracać obiekty za pomocą tej metody. Zwróć uwagę, że jeśli wyślesz zserializowany obiekt Pythona z jythona, a następnie wywołasz funkcje, które zmieniają dane w jego elementach członkowskich, nie zobaczysz tych zmian w java. Musisz tylko pamiętać o odesłaniu żądanych danych z pyro. Myślę, że to najłatwiejszy sposób, aby dostać się do cpython! Nie potrzebujesz żadnego jni, jna, swig lub ... Nie musisz znać żadnego c ani c ++. kool co?
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 pośrednikiem).
Java na C / C ++ przez JNI / JNA / SWIG do Pythona przez wbudowany interpreter (może przy użyciu bibliotek BOOST?)
OMG, ta metoda nie jest dla osób o słabym sercu. I mogę powiedzieć, że zajęło mi to bardzo dużo czasu, zanim udało mi się to osiągnąć przyzwoitą metodą. Głównym powodem, dla którego chciałbyś to zrobić, jest to, że możesz uruchomić kod cpython, który będzie miał pełną kontrolę nad obiektem Java. Przed podjęciem decyzji o spróbowaniu chleba java (który jest jak szympans) z pytonem (który jest jak koń), należy wziąć pod uwagę ważne kwestie. Po pierwsze, jeśli zawiesisz interpreter, który jest wyłączony dla twojego programu! I nie zaczynaj od kwestii współbieżności! Ponadto jest dużo kotła, wierzę, że znalazłem najlepszą konfigurację, aby zminimalizować ten kocioł, ale nadal jest! Jak więc się do tego zabrać: Weź pod uwagę, że C ++ jest twoim pośrednikiem, twoje obiekty to w rzeczywistości obiekty c ++! Dobrze, że już to wiesz. Po prostu napisz swój obiekt tak, jakby twój program był jak w cpp, a nie java, z danymi, do których chcesz uzyskać dostęp z obu światów. Następnie możesz użyć generatora opakowań o nazwie swig (http://www.swig.org/Doc1.3/Java.html ), aby udostępnić to java i skompilować bibliotekę dll, którą wywołujesz System.load (tutaj nazwa dll) w java. Najpierw zajmij się tym, a potem przejdź do najtrudniejszej części! Aby dostać się do Pythona, musisz osadzić interpreter. Po pierwsze proponuję robi kilka programów tłumacza hello czy ten samouczek Osadzanie Pythona w C / C . Kiedy już to zrobisz, pora zmusić konia i małpkę do tańca! Możesz wysłać obiekt C ++ do Pythona przez [boost] [3]. Wiem, że nie dałem ci ryby, powiedziałem tylko, gdzie ją znaleźć. Kilka wskazówek, na które należy zwrócić uwagę podczas kompilacji.
Podczas kompilacji przyspieszenia musisz skompilować bibliotekę współdzieloną. I musisz dołączyć i linkować do rzeczy, których potrzebujesz z jdk, tj. Jawt.lib, jvm.lib (będziesz również potrzebować klienta jvm.dll w swojej ścieżce podczas uruchamiania aplikacji), a także python27.lib lub 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 kłopoty. I tak, w pełni wiem. Jest tak wiele sposobów, w jakie może się to zepsuć. Więc upewnij się, że wykonujesz każdą rzecz blok po bloku. Następnie złóż je razem.
źródło
Nie jest mądrze mieć kod Pythona w java. Zawiń swój kod w języku Python za pomocą platformy flask lub innej platformy internetowej, aby uczynić go mikrousługą. Spraw, aby Twój program java mógł wywoływać tę mikrousługę (np. Przez REST).
Uwierz mi, to jest o wiele proste i pozwoli Ci zaoszczędzić mnóstwo problemów. Kody są luźno powiązane, więc są skalowalne.
Zaktualizowano 24 marca 2020 r .: 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
źródło
Kilka odpowiedzi wspomina, że możesz użyć JNI lub JNA, aby uzyskać dostęp do cpython, ale nie polecałbym zaczynać od zera, ponieważ istnieją już biblioteki open source umożliwiające dostęp do cpython z javy. Na przykład:
źródło
Tutaj biblioteka, która pozwala ci raz napisać skrypty Pythona i zdecydować, której metody integracji (Jython, CPython / PyPy przez 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.
źródło
To zależy od tego, co masz na myśli przez funkcje Pythona? jeśli zostały napisane w cpythonie , nie możesz ich bezpośrednio wywołać, będziesz musiał użyć JNI , ale jeśli zostały napisane w Jythonie możesz je łatwo wywołać z javy, ponieważ jython ostatecznie generuje kod bajtowy java.
Teraz, kiedy mówię napisane w cpythonie lub jythonie, nie ma to większego sensu, ponieważ python to python i większość kodu będzie działać na obu implementacjach, chyba że używasz określonych bibliotek, które opierają się na cpythonie lub javie.
zobacz tutaj, jak używać interpretera Pythona w Javie.
źródło
W zależności od wymagań przydatne mogą być opcje takie jak XML-RPC , które można wykorzystać do zdalnego wywoływania funkcji praktycznie w dowolnym języku obsługującym protokół.
źródło
GraalVM to dobry wybór. Zrobiłem połączenie Java + Javascript z GraalVM do projektowania mikrousług (Java z odzwierciedleniem Javascript). Niedawno dodali obsługę Pythona, spróbuję, szczególnie biorąc pod uwagę, jak duża stała się jego społeczność na przestrzeni lat.
źródło
Możesz wywołać dowolny język z javy przy użyciu natywnego interfejsu Java
źródło
Jython ma pewne ograniczenia:
Rozpowszechnianie moich skryptów w języku Python jako plików JAR w języku Jython?
możesz po prostu wywołać skrypty Pythona (lub skrypty bash lub Perl) z języka Java za pomocą środowiska uruchomieniowego lub ProcessBuilder i przekazać dane wyjściowe z powrotem do języka Java:
Uruchamianie skryptu powłoki bash w java
Uruchamianie wiersza poleceń w Javie
java runtime.getruntime () pobiera dane wyjściowe z wykonania programu wiersza poleceń
źródło
To daje całkiem dobry przegląd ciągu bieżącej opcji. Niektóre z nich są wymienione w innych odpowiedziach. Jython nie nadaje się do użytku, dopóki nie zdecydują się na wdrożenie Pythona 3.x, a wiele innych projektów pochodzi ze strony Pythona i chce mieć dostęp do javy. Ale jest jeszcze kilka opcji, aby nazwać coś, co nie zostało jeszcze nazwane: gRPC
źródło