Jython, использовать только метод из Python из Java?
При чтении и использованииЭта статья Предполагается, что у нас есть полное определение объекта с объектами класса и отображения (прокси) от Python до Java.
Можно ли импортировать только метод (не определенный внутри класса, но использующий внутренний класс python) из фрагмента кода в python, не заключая его в определение класса (без использования описанной выше фабричной парадигмы).
Я хотел бы сделать что-тоfrom myPyFile import myMethod
из Java, а затем использовать myMethod, непосредственно из Java (может быть, в качестве статического метода?)? Но если это возможно, я не нашел ни малейшего понятия о том, как это сделать (интерфейс, описанный в статье, все еще может быть необходим, чтобы сказать Java, как использовать myMethod?)
С наилучшими пожеланиями.
EDIT : Я сейчас имею дело сJython 2.5.2Таким образом, это может быть в зависимости от версии и гораздо проще в будущем?
EDIT : Ниже в ответ Даниэлю:
Вот пример кода, чтобы воспроизвести полученную ошибку, а также получить рабочий пример из вашего полезного ответа!
(Ну и добавим немного другой вопрос по отображению обратно на объекты Java изyield результат Python / Jython)
(@Joonas, извините, я изменил свой код, и теперь я не могу вернуться к ошибке, которая у меня была раньше)
<code>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); } } </code>
Python часть: (mymodule.py)
<code>#!/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() </code>
EDIT :
Частично отвечая себе на внутренний вопрос (внутри комментариев):
(на самом деле я чувствую, что мой ответ и код некрасивы, но это работает и, кажется, нормальноtuple Я не знаю, есть ли лучший Jythonic-способ сделать это, если это так, мне действительно интересно :))
<code>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 + "]"); </code>
EDIT:
Отвечая на вопрос о & quot; производить:"java.lang.ClassCastException: org.python.core.PySingleton cannot be cast to MyInterface"... большинство моих недоразумений и ошибок, связанных с тем, что я забыл обрабатывать Java из части Python! (см. мой код выше, я оставляю это без исправления об этом факте, потому что это не был мой главный вопрос, и в его реальной форме, это рабочий ответ на этот главный вопрос, большое спасибо Даниэлю и Джунасу, которые помогли мне понять). Таким образом, для заводской парадигмы нужноNOT забудьте добавить соответствующий импорт в свой файл Python:
<code>from testjython.interfaces import MyInterface #// defining method inside a MyInterface.java class MyClass(MyInterface): [...] </code>
Еще одна трудность, с которой я столкнулся, заключалась в правильной обработке импорта и пакетов. Кстати, добавление этого кода в верхний код приведет кTypeError: can't convert to org.python.core.PyList но это еще одна проблема ...