Memanggil Python di Java?


Jawaban:


101

Jython: Python untuk Platform Java - http://www.jython.org/index.html

Anda dapat dengan mudah memanggil fungsi python dari kode Java dengan Jython. Itu selama kode python Anda sendiri berjalan di bawah jython, yaitu tidak menggunakan beberapa ekstensi-c yang tidak didukung.

Jika itu berhasil untuk Anda, itu pasti solusi paling sederhana yang bisa Anda dapatkan. Jika tidak, Anda dapat menggunakan org.python.util.PythonInterpreterdari dukungan interpreter Java6 yang baru.

Sebuah contoh sederhana dari atas kepala saya - tetapi semoga berhasil Saya harap: (tidak ada pengecekan kesalahan yang dilakukan untuk singkatnya)

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

Saya telah menginstal JYthon, atau saya berasumsi saya melakukannya, dan saya terus mencoba menjalankan kode yang Anda uraikan tetapi disorot sebagai kesalahan. Apakah instalasi Jython perlu masuk ke folder tertentu, baik di folder python atau java?
Shahab

2
Tidak ada kesalahan, saya hanya kesulitan mengintegrasikan Jython ke Netbeans
Shahab

Jika tidak ada kesalahan itu akan berhasil, jadi itu jelas bukan masalahnya;) "Kesalahan" tidak berarti kesalahan runtime, bisa menjadi kesalahan kompilasi juga.
Voo

Saya buruk, itu adalah penggunaan kata yang buruk. Saya mencoba menambahkan jython.jar ke proyek dan netbeans saya. Saya menemukan jawabannya meskipun
Shahab

1
End of Life Python 2 adalah 1.1.2020 dan Jython hanya mendukung Python 2.7. jadi tidak ada Jython yang pada dasarnya mati. Opsi terbaik (paling sederhana) adalah Jep lib
garyee

63

Hei saya pikir saya akan memasukkan jawaban saya untuk ini meskipun terlambat. Saya pikir ada beberapa hal penting yang perlu dipertimbangkan terlebih dahulu dengan seberapa kuat Anda ingin menghubungkan antara java dan python.

Pertama Apakah Anda hanya ingin memanggil fungsi atau Anda benar-benar ingin kode python mengubah data di objek java Anda? Ini sangat penting. Jika Anda hanya ingin memanggil beberapa kode python dengan atau tanpa argumen, maka itu tidak terlalu sulit. Jika argumen Anda primitif, hal itu membuatnya semakin mudah. Namun jika Anda ingin memiliki kelas java mengimplementasikan fungsi anggota dengan python, yang mengubah data objek java, maka ini tidak begitu mudah atau lurus ke depan.

Kedua, apakah kita berbicara tentang cpython atau akankah jython lakukan? Saya akan mengatakan bahwa cpython adalah tempatnya! Saya akan menganjurkan inilah mengapa python sangat kool! Memiliki abstraksi yang tinggi namun akses ke c, c ++ bila diperlukan. Bayangkan jika Anda bisa memilikinya di java. Pertanyaan ini bahkan tidak layak untuk ditanyakan apakah jython baik-baik saja karena itu mudah pula.

Jadi saya telah bermain dengan metode berikut, dan mendaftarnya dari mudah ke sulit:

Java ke Jython

Keuntungan: Sangat mudah. Memiliki referensi aktual ke objek java

Kekurangan: Tidak Ada CPython, Sangat Lambat!

Jython dari java sangat mudah, dan jika ini benar-benar cukup bagus. Namun itu sangat lambat dan tidak ada cpython! Apakah hidup layak dijalani tanpa cpython, saya rasa tidak! Anda dapat dengan mudah memiliki kode python yang mengimplementasikan fungsi anggota Anda untuk objek java Anda.

Java ke Jython ke CPython melalui Pyro

Pyro adalah modul objek jarak jauh untuk python. Anda memiliki beberapa objek pada interpreter cpython, dan Anda dapat mengirimkan objek yang ditransfer melalui serialisasi dan juga dapat mengembalikan objek melalui metode ini. Perhatikan bahwa jika Anda mengirim objek python serial dari jython dan kemudian memanggil beberapa fungsi yang mengubah data di anggotanya, maka Anda tidak akan melihat perubahan tersebut di java. Anda hanya perlu mengingat untuk mengirim kembali data yang Anda inginkan dari pyro. Ini saya percaya adalah cara termudah untuk sampai ke cpython! Anda tidak membutuhkan jni atau jna atau swig atau .... Anda tidak perlu tahu c, atau c ++. kool ya?

Keuntungan: Akses ke cpython, tidak sesulit metode berikut

Kekurangan: Tidak dapat mengubah data anggota objek java langsung dari python. Agak tidak langsung, (jython adalah orang tengah).

Java ke C / C ++ melalui JNI / JNA / SWIG ke Python melalui penerjemah Tertanam (mungkin menggunakan Pustaka BOOST?)

OMG metode ini bukan untuk yang lemah hati. Dan saya dapat memberitahu Anda bahwa saya butuh waktu sangat lama untuk mencapai ini dengan metode yang layak. Alasan utama Anda ingin melakukan ini adalah agar Anda dapat menjalankan kode cpython yang sebagai kendali penuh atas objek java Anda. Ada beberapa hal utama yang perlu dipertimbangkan sebelum memutuskan untuk mencoba dan roti java (yang seperti simpanse) dengan python (yang seperti kuda). Pertama jika Anda merusak penerjemah yang menyala untuk Anda program! Dan jangan biarkan saya memulai masalah konkurensi! Selain itu, ada alokasi membagikan boiler, saya yakin saya telah menemukan konfigurasi terbaik untuk meminimalkan boiler ini tetapi tetap saja membagikan! Jadi bagaimana melakukan ini: Pertimbangkan bahwa C ++ adalah perantara Anda, objek Anda sebenarnya adalah objek c ++! Bagus karena kamu tahu itu sekarang. Tulis saja objek Anda seolah-olah program Anda seperti di cpp bukan java, dengan data yang ingin Anda akses dari kedua dunia. Kemudian Anda dapat menggunakan generator pembungkus yang disebut swig (http://www.swig.org/Doc1.3/Java.html ) agar ini dapat diakses oleh java dan kompilasi dll yang Anda sebut System.load (nama dll di sini) di java. Kerjakan ini dulu, lalu lanjutkan ke bagian yang sulit! Untuk mendapatkan python Anda perlu menyematkan seorang juru bahasa. Pertama saya sarankan melakukan beberapa program interpreter Halo atau tutorial ini Menanamkan python di C / C . Setelah Anda berhasil melakukannya, saatnya membuat kuda dan monyet menari! Anda dapat mengirimi Anda objek c ++ ke python melalui [boost] [3]. Saya tahu saya belum memberi Anda ikan itu, hanya memberi tahu Anda di mana menemukan ikan itu. Beberapa petunjuk yang perlu diperhatikan untuk ini saat menyusun.

Saat Anda mengkompilasi dorongan, Anda perlu mengkompilasi perpustakaan bersama. Dan Anda perlu menyertakan dan menautkan ke hal-hal yang Anda butuhkan dari jdk, yaitu jawt.lib, jvm.lib, (Anda juga memerlukan klien jvm.dll di jalur Anda saat meluncurkan aplikasi) Serta python27.lib atau terserah dan boost_python-vc100-mt-1_55.lib. Kemudian sertakan Python / include, jdk / include, boost dan hanya gunakan pustaka bersama (dll) jika tidak boost akan berlinang air mata. Dan ya, saya tahu. Ada begitu banyak cara untuk membuat ini menjadi masam. Jadi pastikan Anda menyelesaikan setiap hal blok demi blok. Kemudian satukan.


2
Di sini pustaka yang memungkinkan Anda menulis skrip python Anda sekali dan memutuskan metode integrasi mana (Jython, CPython melalui Jep dan Py4j) yang akan digunakan saat runtime: github.com/subes/invesdwin-context-python Karena setiap metode memiliki kelebihan / kekurangannya sendiri
subes

@subes proyek itu tampak luar biasa Saya menulis ini beberapa waktu yang lalu. Saya mendorong Anda untuk menulis jawaban yang akan saya beri suara positif. Saya tidak suka jawaban teratas haha ​​karena menurut saya jawaban itu tidak memberikan banyak informasi berguna di luar pencarian google.
Snickers3192

Saya membuat jawaban terpisah
subes

3
apakah jawaban ini berbau "ini harus menjadi jawaban yang diterima" atau hanya saya? ;-)
Mauricio Gracia Gutierrez

18

Tidak pintar memiliki kode python di dalam java. Bungkus kode python Anda dengan flask atau kerangka web lain untuk menjadikannya sebagai layanan mikro. Jadikan program java Anda dapat memanggil layanan mikro ini (misalnya melalui REST).

Percayalah, ini jauh lebih sederhana dan akan menyelamatkan Anda dari banyak masalah. Dan kode tersebut digabungkan secara longgar sehingga dapat diskalakan.

Diperbarui pada 24 Mar 2020: Menurut komentar @ stx, pendekatan di atas tidak cocok untuk transfer data besar-besaran antara klien dan server. Berikut adalah pendekatan lain yang saya rekomendasikan: Menghubungkan Python dan Java dengan Rust (C / C ++ juga ok). https://medium.com/@shmulikamar/https-medium-com-shmulikamar-connecting-python-and-java-with-rust-11c256a1dfb0


+1, tetapi bagaimana dengan kinerja tambahan dan overhead komunikasi dalam membuat dan mengurai pesan bolak-balik di kedua ujungnya?
stx

ya, ini perlu mendefinisikan antarmuka api dengan input / output minimum yang diperlukan. Tidaklah pintar memiliki banyak transfer data antara klien / server di jaringan. Jika Anda tidak dapat menentukan antarmuka seperti itu, maka pendekatan desain ini tidak cocok.
Peiming Hu

10

Beberapa jawaban menyebutkan bahwa Anda dapat menggunakan JNI atau JNA untuk mengakses cpython tetapi saya tidak akan merekomendasikan memulai dari awal karena sudah ada pustaka sumber terbuka untuk mengakses cpython dari java. Sebagai contoh:


8

Di sini pustaka yang memungkinkan Anda menulis skrip python Anda sekali dan memutuskan metode integrasi mana (Jython, CPython / PyPy via Jep dan Py4j) yang akan digunakan saat runtime:

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

Karena setiap metode memiliki kelebihan / kekurangannya sendiri seperti yang dijelaskan di tautan.


Proyek ini tidak memiliki rilis apa pun.
Christian Schlichtherle

@ChristianSchlichtherle invesdwin-context-python versi 1.0.0 tidak tersedia; terima kasih untuk permata kecil ini: github.com/loewenfels/dep-graph-releaser
subes

6

Itu tergantung pada apa yang Anda maksud dengan fungsi python? jika mereka ditulis dalam cpython Anda tidak dapat langsung memanggilnya Anda harus menggunakan JNI , tetapi jika mereka ditulis dalam Jython Anda dapat dengan mudah memanggil mereka dari java, karena jython pada akhirnya menghasilkan kode byte java.

Sekarang ketika saya mengatakan ditulis dalam cpython atau jython itu tidak masuk akal karena python adalah python dan sebagian besar kode akan berjalan pada kedua implementasi kecuali Anda menggunakan pustaka tertentu yang bergantung pada cpython atau java.

lihat di sini cara menggunakan interpreter Python di Java.


5

Bergantung pada kebutuhan Anda, opsi seperti XML-RPC dapat berguna, yang dapat digunakan untuk memanggil fungsi dari jarak jauh secara virtual dalam bahasa apa pun yang mendukung protokol.


5

GraalVM adalah pilihan yang bagus. Saya telah melakukan kombinasi Java + Javascript dengan GraalVM untuk desain microservice (Java dengan refleksi Javascript). Mereka baru-baru ini menambahkan dukungan untuk python, saya akan mencobanya terutama dengan seberapa besar komunitasnya selama bertahun-tahun.


4

Anda dapat memanggil bahasa apa pun dari java menggunakan Java Native Interface


6
Bahasa apa pun itu sendiri dapat dipanggil dari c itu. Baiklah python bisa, tapi Jython adalah solusi yang jauh lebih sederhana di sana (atau menggunakan PyInterpreter di j6 +). Tidak sepele untuk menulis kode untuk memanggil fungsi python dari c.
Voo

2

Jython memiliki beberapa batasan:

Ada sejumlah perbedaan. Pertama, program Jython tidak dapat menggunakan modul ekstensi CPython yang ditulis dalam C. Modul ini biasanya memiliki file dengan ekstensi .so, .pyd atau .dll. Jika Anda ingin menggunakan modul seperti itu, Anda harus mencari padanan yang ditulis dalam Python atau Java murni. Meskipun secara teknis memungkinkan untuk mendukung ekstensi seperti itu - IronPython melakukannya - tidak ada rencana untuk melakukannya di Jython.

Mendistribusikan skrip Python saya sebagai file JAR dengan Jython?

Anda cukup memanggil skrip python (atau bash atau skrip Perl) dari Java menggunakan Runtime atau ProcessBuilder dan meneruskan keluaran kembali ke Java:

Menjalankan skrip bash shell di java

Menjalankan Command Line di Java

java runtime.getruntime () mendapatkan keluaran dari menjalankan program baris perintah


0

Ini memberikan gambaran umum yang cukup bagus tentang opsi saat ini. Beberapa di antaranya disebutkan dalam jawaban lain. Jython tidak dapat digunakan sampai mereka memutuskan untuk mengimplementasikan Python 3.x dan banyak proyek lain yang datang dari sisi python dan ingin mengakses java. Namun masih ada beberapa opsi, untuk memberi nama sesuatu yang belum dinamai: gRPC

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.