Jython, nur eine Methode von Python aus Java verwenden?

Beim Lesen und VerwendenDieser Beitrag Es wird davon ausgegangen, dass wir eine vollständige Objektdefinition mit Klassen- und Zuordnungsobjekten (Proxy-Objekten) von Python bis Java haben.

Ist es möglich, nur eine Methode (die nicht in einer Klasse definiert ist, sondern die interne Python-Klasse verwendet) aus einem Teil des Codes in Python zu importieren, ohne ihn in eine Klassendefinition einzufügen (ohne das oben beschriebene Factory-Paradigma zu verwenden)?

Ich hätte gerne eine Art gemachtfrom myPyFile import myMethod aus Java, und dann myMethod verwenden, direkt aus Java (vielleicht als statische Methode?)? Aber wenn dies möglich ist, habe ich keine Ahnung, wie das gemacht wird (das im Artikel beschriebene Interface-Zeug ist möglicherweise noch erforderlich, um Java mitzuteilen, wie man myMethod benutzt?)

Freundliche Grüße.

BEARBEITEN : Ich beschäftige mich jetzt mitJython 2.5.2kann es also versionsabhängig und in Zukunft viel einfacher sein?

EDIT: Unten als Antwort auf Daniel:

Hier ist ein Beispielcode, um den Fehler zu reproduzieren, den ich erhalte, und um ein funktionierendes Beispiel aus Ihrer hilfreichen Antwort zu erhalten!

(Nun, und fügen Sie eine weitere Frage zum Mapping auf Java-Objekte von a hinzuAusbeute -ed Python / Jython-Ergebnis)

(@Joonas, Entschuldigung, ich habe meinen Code geändert und kann jetzt nicht mehr zu dem Fehler zurückkehren, den ich früher hatte.)

<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-Teil: (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>

BEARBEITEN :

Teilweise antworte ich für die innere Frage (in Kommentaren):
(Eigentlich finde ich meine Antwort und meinen Code hässlich, aber es funktioniert und scheint in Ordnung zu sein,Tupel Ich weiß nicht, ob es eine bessere Jythonic-Methode gibt, wenn ja, bin ich wirklich interessiert :))

<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>


BEARBEITEN:

Beantworte mich auf den Teil über "Produziere ein:"java.lang.ClassCastException: org.python.core.PySingleton kann nicht in MyInterface umgewandelt werden"... die meisten meiner Missverständnisse und Fehler waren darauf zurückzuführen, dass ich vergessen hatte, mit Java aus dem Python-Teil umzugehen! (Siehe meinen obigen Code, ich lasse ihn unkorrigiert, da dies nicht meine Hauptfrage war. In seiner tatsächlichen Form ist es eine funktionierende Antwort auf diese Hauptfrage. Vielen Dank an Daniel und Joonas, die mir geholfen haben, das zu verstehen.) Für das Fabrikparadigma sollte man es also tunNICHT Vergessen Sie, den entsprechenden Import in die Python-Datei einzufügen:

<code>from testjython.interfaces import MyInterface #// defining method inside a MyInterface.java

class MyClass(MyInterface):
    [...]
</code>

Eine andere Schwierigkeit, die ich hatte, war, den Import und die Pakete richtig zu behandeln. Übrigens erzeugt das Hinzufügen dieses Codes zum oberen Code einTypeError: Kann nicht in org.python.core.PyList konvertiert werden aber das ist ein anderes Anliegen ...

Antworten auf die Frage(2)

Ihre Antwort auf die Frage