Yanıtlar:
Jython: Java Platformu için Python - http://www.jython.org/index.html
Python işlevlerini Jython ile Java kodundan kolayca çağırabilirsiniz. Bu, python kodunuzun kendisi jython altında çalıştığı, yani desteklenmeyen bazı c uzantılarını kullanmadığı sürece geçerlidir.
Bu sizin için işe yararsa, kesinlikle alabileceğiniz en basit çözümdür. Aksi takdirde org.python.util.PythonInterpreter
yeni Java6 yorumlayıcı desteğinden kullanabilirsiniz.
Kafamın tepesinden basit bir örnek - ama işe yaramalı umarım: (kısalık için hata kontrolü yapılmaz)
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);
Hey geç de olsa buna cevabımı gireceğimi düşündüm. Java ve python arasındaki bağın ne kadar güçlü olmasını istediğinizle ilgili olarak öncelikle dikkate alınması gereken bazı önemli şeyler olduğunu düşünüyorum.
İlk olarak, yalnızca işlevleri mi çağırmak istiyorsunuz yoksa python kodunun java nesnelerinizdeki verileri değiştirmesini mi istiyorsunuz? Bu çok önemli. Sadece bazı python kodunu bağımsız değişkenli veya bağımsız olarak çağırmak istiyorsanız, o zaman bu çok zor değil. İddialarınız ilkelse, daha da kolaylaştırır. Bununla birlikte, java sınıfının, java nesnesinin verilerini değiştiren python'da üye işlevlerini uygulamasına sahip olmak istiyorsanız, bu o kadar kolay veya düz değildir.
İkincisi , cpython'dan mı bahsediyoruz yoksa jython mu yapacak? Cpython'un nerede olduğunu söyleyebilirim! Bu yüzden python bu kadar kool! Bu kadar yüksek soyutlamalara sahip olmak, ancak gerektiğinde c, c ++ 'ya erişim. Buna java'da sahip olabileceğinizi hayal edin. Bu soru jython'un uygun olup olmadığını sormaya bile değmez çünkü o zaman zaten kolaydır.
Bu yüzden aşağıdaki yöntemlerle oynadım ve bunları kolaydan zora doğru sıraladım:
Java'dan Jython'a
Avantajlar: Oldukça kolay. Java nesnelerine gerçek referanslar var
Dezavantajları: CPython Yok, Son Derece Yavaş!
Java'dan Jython çok kolay ve bu gerçekten yeterliyse harika. Ancak çok yavaş ve cpython yok! Cpython olmadan yaşam yaşamaya değer mi? Sanmıyorum! Java nesneleri için üye işlevlerinizi uygulayan python koduna kolayca sahip olabilirsiniz.
Pyro aracılığıyla Java'dan Jython'dan CPython'a
Pyro, python için uzak nesne modülüdür. Bir cpython yorumlayıcısında bir nesneniz var ve ona serileştirme yoluyla aktarılan nesneleri gönderebilir ve bu yöntemle nesneleri de döndürebilir. Jython'dan serileştirilmiş bir python nesnesi gönderir ve ardından üyelerindeki verileri değiştiren bazı işlevleri çağırırsanız, bu değişiklikleri java'da görmeyeceğinizi unutmayın. Pyro'dan istediğiniz verileri geri göndermeyi hatırlamanız yeterlidir. Bunun cpython'a ulaşmanın en kolay yolu olduğuna inanıyorum! Herhangi bir jni ya da jna ya da swig ya da .... bilmenize gerek yok. kool ha?
Avantajlar: cpython'a erişim, aşağıdaki yöntemler kadar zor değil
Dezavantajlar: Java nesnelerinin üye verilerini doğrudan python'dan değiştiremezsiniz. Biraz dolaylıdır, (jython orta adamdır).
Java'dan C / C ++ 'ya JNI / JNA / SWIG'den Python'a Gömülü yorumlayıcı aracılığıyla (belki BOOST Kitaplıkları kullanılarak?)
OMG bu yöntem kalbin zayıfları için değildir. Bunu düzgün bir yöntemle başarmamın çok uzun sürdüğünü size söyleyebilirim. Bunu yapmak istemenizin ana nedeni, java nesnenizi tamamen kontrol altında tutan cpython kodunu çalıştırabilmenizdir. (Bir şempanze gibi olan) java'yı python (bir at gibi) ile denemeye karar vermeden önce göz önünde bulundurulması gereken önemli şeyler var. Öncelikle tercümanı çökertirseniz, program sizin için yanar! Ve beni eşzamanlılık sorunlarına sokmayın! Ek olarak, kazan tahsisi var, bu kazanı en aza indirmek için en iyi konfigürasyonu bulduğuma inanıyorum, ancak yine de tahsis edilmiş durumda! Peki bunun nasıl yapılacağı: C ++ 'ın aracınız olduğunu düşünün, nesneleriniz aslında c ++ nesneleridir! Artık bunu bilmen güzel. Sadece nesnenizi java değil cpp'deki gibi yazın, her iki dünyadan da erişmek istediğiniz verilerle. Daha sonra swig adlı sarıcı oluşturucuyu kullanabilirsiniz (http://www.swig.org/Doc1.3/Java.html ) bunu java için erişilebilir hale getirmek ve java'da System.load (dll adı burada) olarak adlandırdığınız bir dll'yi derlemek için. Önce bunu çalıştır, sonra zor kısma geç! Python'a ulaşmak için bir yorumlayıcı yerleştirmeniz gerekir. Öncelikle, bazı merhaba tercüman programları veya bu öğretici Python'u C / C'ye Gömme yapmanızı öneririm . Bunu çalıştırdıktan sonra, at ve maymunu dans ettirme zamanı! [Boost] [3] aracılığıyla python'a c ++ nesnesi gönderebilirsiniz. Sana balığı vermediğimi biliyorum, sadece balığı nerede bulacağını söyledim. Derleme sırasında bunun için dikkat edilmesi gereken bazı noktalar.
Boost derlediğinizde, paylaşılan bir kitaplık derlemeniz gerekecek. Ve jdk'den ihtiyacınız olan şeyleri eklemeniz ve bunlara bağlantı vermeniz gerekir, yani jawt.lib, jvm.lib (uygulamayı başlatırken yolunuzda jvm.dll istemcisine de ihtiyacınız olacaktır) ve python27.lib veya ne olursa olsun ve boost_python-vc100-mt-1_55.lib. Ardından Python / include, jdk / include, boost'u dahil edin ve yalnızca paylaşılan kitaplıkları (dll'ler) kullanın, aksi takdirde boost çok zor olur. Ve evet tam biliyorum. Bunun bozulabileceği pek çok yol var. Bu nedenle, her bir şeyi bloklar halinde yaptığınızdan emin olun. Sonra onları bir araya getirin.
Java içinde python koduna sahip olmak akıllıca değil. Python kodunuzu, mikro hizmet olarak yapmak için flask veya başka bir web çerçevesine sarın. Java programınızın bu mikro hizmeti çağırabilmesini sağlayın (örn. REST aracılığıyla).
İnanın bana, bu çok basit ve sizi tonlarca sorundan kurtaracak. Ve kodlar gevşek bir şekilde birleştirildiğinden ölçeklenebilirler.
24 Mart 2020'de güncellendi: @ stx'in yorumuna göre, yukarıdaki yaklaşım istemci ile sunucu arasında büyük veri aktarımı için uygun değildir. İşte önerdiğim başka bir yaklaşım: Python ve Java'yı Rust ile Bağlamak (C / C ++ da tamam). https://medium.com/@shmulikamar/https-medium-com-shmulikamar-connecting-python-and-java-with-rust-11c256a1dfb0
Python komut dosyalarınızı bir kez yazmanıza ve çalışma zamanında hangi entegrasyon yöntemini (Jep ve Py4j üzerinden Jython, CPython / PyPy) kullanmanıza olanak tanıyan bir kitaplık:
https://github.com/subes/invesdwin-context-python
Bağlantıda açıklandığı gibi her yöntemin kendi yararları / sakıncaları olduğundan.
Python fonksiyonları ile ne demek istediğine bağlı mı? Onlar yazılmış olsaydı CPython doğrudan kullanmak zorunda kalacak onları diyemezsin JNI , ancak yazılı olsaydı Jython jython sonuçta java byte kod üretir olarak kolayca java onları çağırabilir.
Şimdi cpython veya jython ile yazılmış dediğimde bu pek bir anlam ifade etmiyor çünkü python python ve çoğu kod, cpython veya java'ya dayanan belirli kitaplıkları kullanmadığınız sürece her iki uygulamada da çalışacak.
Java'da Python yorumlayıcısının nasıl kullanılacağına bakın .
GraalVM iyi bir seçimdir. Mikro hizmet tasarımı için GraalVM ile Java + Javascript kombinasyonu yaptım (Javascript yansımalı Java). Yakın zamanda python için destek eklediler, özellikle topluluğunun yıllar içinde ne kadar büyük hale geldiğine bakarım.
Java Native Interface'i kullanarak java'dan herhangi bir dili arayabilirsiniz
Jython'un bazı sınırlamaları vardır:
Bir takım farklılıklar var. İlk olarak, Jython programları C'de yazılmış CPython eklenti modüllerini kullanamazlar. Bu modüller genellikle .so, .pyd veya .dll uzantılı dosyalara sahiptir. Böyle bir modül kullanmak istiyorsanız, saf Python veya Java ile yazılmış bir eşdeğerini aramalısınız. Bu tür uzantıları desteklemek teknik olarak uygun olsa da - IronPython öyle yapar - Jython'da bunu yapmak için herhangi bir plan yoktur.
Python komut dosyalarımı Jython ile JAR dosyaları olarak dağıtmak?
Runtime veya ProcessBuilder kullanarak Java'dan python komut dosyalarını (veya bash veya Perl komut dosyalarını) çağırabilir ve çıktıyı Java'ya geri iletebilirsiniz:
Java'da bir bash kabuğu komut dosyası çalıştırma
Java'da Komut Satırını Çalıştırma
java runtime.getruntime () bir komut satırı programını yürütmekten çıktı alıyor
Bu , mevcut seçenekler hakkında oldukça iyi bir genel bakış sağlar. Bazıları başka cevaplarda isimlendirilmiştir. Jython, Python 3.x'i uygulamaya karar verene kadar kullanılamaz ve diğer projelerin çoğu python tarafından geliyor ve java'ya erişmek istiyor. Ancak henüz adlandırılmamış bir şeyi adlandırmak için hala birkaç seçenek var: gRPC