この記事を読んで使用するときは、クラスとPythonからJavaへのマッピング(プロキシ)オブジェクトを含む完全なオブジェクト定義があることを前提としています。
クラス定義でラップせずに(上記のファクトリパラダイムを使用せずに)Pythonのコードの一部からメソッド(クラス内で定義されていないが、内部pythonクラスを使用)のみをインポートすることは可能ですか?
ある種のfrom myPyFile import myMethod
Javaから実行してから、myMethodをJavaから直接使用する必要があります(おそらく静的メソッドとして?)?しかし、これが可能である場合、それをどのように行うかについての手がかりは見つかりませんでした(JavaにmyMethodの使用方法を指示するには、記事で説明されているインターフェイスのものがまだ必要な場合がありますか?)
よろしくお願いします。
編集:私は現在Jython 2.5.2を扱っているので、バージョンに依存し、将来的にははるかに簡単になる可能性がありますか?
編集:ダニエルへの返信で以下:
これがサンプルコードです。私が得たエラーを再現し、役立つ返信から実用的な例を取得します。
(そして、 yield -ed Python / Jythonの結果からJavaオブジェクトへのマッピングに戻るためのもう少し質問を追加します)
(@Joonas、申し訳ありませんが、コードを変更しましたが、以前のエラーに戻ることができなくなりました)
import org.python.core.Py;
import org.python.core.PyList;
import org.python.core.PyTuple;
import org.python.core.PyObject;
import org.python.core.PyString;
import org.python.core.PySystemState;
import org.python.util.PythonInterpreter;
interface MyInterface {
public PyList getSomething(String content, String glue, boolean bool);
}
class MyFactory {
@SuppressWarnings("static-access")
public MyFactory() {
String cmd = "from mymodule import MyClass";
PythonInterpreter interpreter = new PythonInterpreter(null, new PySystemState());
PySystemState sys = Py.getSystemState();
sys.path.append(new PyString("C:/jython2.5.2/Lib"));
interpreter.exec(cmd);
jyObjClass = interpreter.get("MyClass");
}
public MyInterface createMe() {
PyObject myObj = jyObjClass.__call__();
return (MyInterface)myObj.__tojava__(MyInterface.class);
}
private PyObject jyObjClass;
}
public class Main {
public static void main(String[] args) {
/*
// with only :
PythonInterpreter interpreter = new PythonInterpreter();
i get :
Exception in thread "main" Traceback (most recent call last):
File "<string>", line 1, in <module>
LookupError: no codec search functions registered: can't find encoding 'iso8859_1'
which is probably due to the :
#!/usr/bin/env python
# -*- coding: latin-1 -*-
// yes i am from France, so my - sorry for that - bad english ;) and have to deal with non 127 ascii chars :)
*/
PythonInterpreter interpreter = new PythonInterpreter(null, new PySystemState());
PySystemState sys = Py.getSystemState();
sys.path.append(new PyString("C:/jython2.5.2/Lib"));
interpreter.exec("from mymodule import getSomething");
PyObject tmpFunction = interpreter.get("getSomething");
System.err.println(tmpFunction.getClass());
MyInterface i = (MyInterface) tmpFunction.__tojava__(MyInterface.class);
System.err.println(i.getSomething("test", " - ", true));
for (Object x : i.getSomething("test", " - ", true)) {
System.out.println(x);
// How can i get back an equivallent of the Python _"for (a, b) in getSomething:"_
// with _"a"_ being PyUnicode or better String, and _"b"_ being boolean ?
}
// ^^ so adapting Daniel Teply solution works ! Thanks to him...
// BTW the part below did not work : but i may have missed or/and also mixed many things :/
// i feel Jython damned hard to dive in :/
// and really hope that the sample that i post and answers that i get will help others to swim!
try {
MyFactory factory = new MyFactory();
MyInterface myobj = factory.createMe();
PyList myResult = myobj.getSomething("test", " - ", true);
System.out.println(myResult);
}
catch (Exception e) {
System.out.println(e);
// produce a : java.lang.ClassCastException: org.python.core.PySingleton cannot be cast to MyInterface
// EDIT : see below last edit, this error may be due to my forgotten heritage from interface in the python code!
}
System.exit(-1);
}
}
Pythonの部分:(mymodule.py)
#!/usr/bin/env python
# -*- coding: latin-1 -*-
class MyClass:
def __init__(selfself):
pass
def getSomething(self, content, glue = '', bool = True):
for x in range(5):
yield (glue.join(map(str, (content, x, chr(97 + x))))), bool
#return list()
def getSomething(content, glue = '', bool = True):
print "test"
myclass = MyClass()
return list(myclass.getSomething(content, glue, bool))
def main():
test()
if __name__ == "__main__":
main()
編集:
内側の質問(コメント内)について、部分的に自分自身に答えます:(
実際、私の答えとコードは醜いと感じますが、それは機能し、より良いJythonicの方法があるかどうかはわかりません。もしそうなら、私は本当に興味があります:))
for (Object x : i.getSomething("test", " - ", true)) {
System.out.println(x);
// How can i get back an equivallent of the Python _"for (a, b) in getSomething:"_
// with _"a"_ being PyUnicode or better String, and _"b"_ being boolean ?
// answering myself here :
PyTuple mytuple = (PyTuple) x; // casting back x as PyTuple, can we have a java equivalent to _`(a, b) = x_ ? not sure...
PyObject a = mytuple.__getitem__(0);
PyObject b = mytuple.__getitem__(1);
String aS = a.toString(); // mapping a unicode python string to java is as simple?
boolean bB = b.toString().toLowerCase().equals("true");
System.out.println(mytuple + "[" + aS + "][" + b + "][" + bB + "]");
編集:
「プロデュース:」に関する部分に自分自身に答えるjava.lang.ClassCastException:org.python.core.PySingletonはMyInterfaceにキャストできません...私の誤解とエラーのほとんどは、私が忘れていたという事実のためですPythonの部分からJavaを処理するために!(上記の私のコードを参照してください。これは私の主な質問ではなかったので、この事実については訂正せずに残します。実際の形式では、この主な質問についての実用的な答えです。ダニエルと私が理解するのを手伝ってくれたJoonas)。したがって、ファクトリパラダイムの場合、Pythonファイルに適切なインポートを追加することを忘れないでください。
from testjython.interfaces import MyInterface #// defining method inside a MyInterface.java
class MyClass(MyInterface):
[...]
私が抱えていたもう1つの問題は、インポートとパッケージを正しく処理することでした。ところで、このコードを上位のコードに追加すると、TypeErrorが生成されます:org.python.core.PyListに変換できませんが、これは別の懸念事項です...