Khi đọc và sử dụng this article, giả định rằng chúng tôi có định nghĩa đối tượng đầy đủ với các đối tượng lớp và ánh xạ (proxy) từ python đến java.Jython, chỉ sử dụng một phương thức từ Python từ Java?
Chỉ có thể nhập phương thức (không được định nghĩa bên trong lớp, nhưng sử dụng lớp python nội bộ) từ một đoạn mã trong python mà không gói nó trong định nghĩa lớp (không sử dụng mô hình nhà máy được mô tả ở trên).
Tôi muốn làm một số loại from myPyFile import myMethod
từ java, và sau đó sử dụng myMethod, trực tiếp từ java (có thể là một phương thức tĩnh?)? Nhưng nếu điều này là có thể, tôi không tìm thấy bất kỳ đầu mối nào về cách thực hiện điều đó (các giao diện được mô tả trong bài viết có thể vẫn cần thiết để nói với Java cách sử dụng myMethod?)
Trân trọng.
EDIT: bây giờ tôi đối phó với Jython 2.5.2, vì vậy nó có thể là phiên bản phụ thuộc và dễ dàng hơn nhiều trong tương lai?
EDIT: Dưới in reply to Daniel:
Dưới đây là một mẫu mã, để tạo lại lỗi tôi nhận được, và cũng có thể có được một ví dụ làm việc kể từ trả lời hữu ích của bạn!
(Vâng và thêm một chút câu hỏi khác về việc lập bản đồ trở lại các đối tượng Java từ một năng suất -ed Python/Jython kết quả)
(@Joonas, Xin lỗi, tôi đã sửa đổi mã của tôi, và bây giờ tôi tôi không thể lùi lại đến lỗi mà tôi đã từng có)
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 phần: (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()
EDIT:
một phần trả lời bản thân mình, cho câu hỏi bên trong (bình luận bên trong):
(thực sự tôi cảm thấy câu trả lời và mã của tôi là xấu xí, nhưng nó hoạt động và có vẻ là ok để UN-tuple tôi làm không biết nếu có một Jythonic-cách tốt hơn để làm điều đó, nếu như vậy, tôi thực sự quan tâm :))
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 + "]");
EDIT:
Trả lời bản thân về phần "sản xuất a: " java.lang.ClassCastException: org.python.core.PySingleton không thể truyền sang MyInterface " ... hầu hết sự hiểu lầm và lỗi của tôi do thực tế là tôi đã quên để xử lý Java từ phần Python! (xem mã của tôi ở trên, tôi để nó không được giải thích về thực tế này bởi vì nó không phải là câu hỏi chính của tôi, và ở dạng thực tế của nó, đó là câu trả lời làm việc về câu hỏi chính này, cảm ơn Daniel và Joonas đã giúp tôi hiểu).Vì vậy, đối với mô hình nhà máy, ta nên KHÔNG quên thêm việc nhập khẩu đầy đủ đến file Python của nó:
from testjython.interfaces import MyInterface #// defining method inside a MyInterface.java
class MyClass(MyInterface):
[...]
Một khó khăn khác mà tôi đã có được để xử lý một cách chính xác việc nhập khẩu và các gói. BTW, thêm mã này vào mã trên sẽ tạo ra một TypeError : không thể chuyển đổi sang org.python.core.PyList nhưng đây là mối quan tâm khác ...
Tôi không biết bất cứ cách nào tốt hơn để phần unpact của tuple trên java bên khác hơn là đúc để PyTuple. Cá nhân, tôi sẽ tạo ra một bên hàm python thứ hai để giải nén trên giá trị trả về của hàm thực. –