Python'u Java'da mı arıyorsunuz?


117

Python işlevlerini jython kullanarak java kodundan çağırmanın mümkün olup olmadığını merak ediyorum, yoksa sadece python'dan java kodunu aramak için mi?


3
Lütfen benzer soruya bir göz atın ve cevabı okuyun. bytes.com/topic/python/answers/…
AlexR

Yanıtlar:


101

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

JYthon'u yükledim veya yaptığımı sanıyorum ve ana hatlarıyla belirttiğiniz kodu çalıştırmaya çalışıyorum ama bir hata olarak vurgulandı. Jython kurulumunun python veya java klasörlerindeki belirli bir klasöre gitmesi gerekiyor mu?
Shahab

2
Herhangi bir hata yok, Jython'u Netbeans'e entegre etmekte zorlanıyorum
Shahab

Hata yoksa işe yarayacaktır, bu yüzden durum böyle değildir;) "Hata" çalışma zamanı hatası anlamına gelmez, bir derleme hatası da olabilir.
Voo

Benim hatam, kelimenin kötü bir kullanımıydı. Jython.jar dosyasını projeme ve netbeans'a eklemeye çalışıyordum. Yine de anladım
Shahab

1
Python 2 Hayatın Sonu 1.1.2020'dir ve Jython yalnızca Python 2.7'yi destekler. yani hiçbir Jython temelde ölmedi. En iyi (en basit) seçenek Jep
lib'dir

63

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.


2
Burada python komut dosyalarınızı bir kez yazmanıza ve çalışma zamanında hangi entegrasyon yönteminin (Jython, CPython aracılığıyla Jep ve Py4j aracılığıyla) kullanılacağına karar vermenize olanak sağlayan bir kitaplık: github.com/subes/invesdwin-context-python Her yöntemin kendi avantajları / dezavantajları olduğu için
2017

@subes bu proje harika görünüyor bunu bir süre önce yazmıştım. Size bir cevap yazmanızı öneririm, ona oy vereceğim. En iyi yanıtı beğenmedim haha ​​çünkü bir google araması dışında pek yararlı bilgi sağladığını düşünmüyorum.
Snickers3192

Ayrı bir cevap oluşturdum
Subes

3
bu cevap "kabul edilen cevap bu olmalı" nın kokusunu alıyor mu yoksa sadece ben miyim? ;-)
Mauricio Gracia Gutierrez

18

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


+1, ancak her iki uçta mesajlar oluşturmanın ve ileri geri ayrıştırmanın ek performans ve iletişim ek yükü ne olacak?
stx

evet, bunun gerekli minimum giriş / çıkışa sahip bir api arayüzü tanımlaması gerekir. Ağdaki istemci / sunucu arasında çok fazla veri aktarımına sahip olmak akıllıca değildir. Böyle bir arayüz tanımlayamazsanız, bu tasarım yaklaşımı uygun değildir.
Peiming Hu

10

Cevaplardan birkaçı, cpython'a erişmek için JNI veya JNA'yı kullanabileceğinizi belirtiyor, ancak cpython'a java'dan erişmek için zaten açık kaynak kütüphaneleri olduğundan sıfırdan başlamayı önermiyorum. Örneğin:


8

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.


Bu projenin herhangi bir sürümü yok.
Christian Schlichtherle

@ChristianSchlichtherle investdwin-bağlam-python sürüm 1.0.0 mevcut değil; Bu küçük cevher için teşekkürler: github.com/loewenfels/dep-graph-releaser
subes

6

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 .


5

Gereksinimlerinize bağlı olarak , protokolü destekleyen herhangi bir dilde işlevleri uzaktan çağırmak için kullanılabilen XML-RPC gibi seçenekler yararlı olabilir.


5

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.


4

Java Native Interface'i kullanarak java'dan herhangi bir dili arayabilirsiniz


6
C'den çağrılabilen herhangi bir dil. Tamam python yapabilir, ancak Jython gerçekten çok daha basit bir çözümdür (veya j6 + 'da PyInterpreter kullanarak). C'den python işlevlerini çağırmak için kod yazmak o kadar da önemsiz değil.
Voo

2

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


0

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.