From: Jakob S. <pj...@ip...> - 2001-12-12 15:51:55
|
Hi again, sorry for these repeated questions about __findattr__, but I just can't get it to work properly. When I define __findattr__(String s) in my Java class, I will get attribute errors for method calls from Jython on all methods in my Java class. In the following example, which consists of two small files, I will get AttributeError: instance of 'Test' has no attribute 'info' Is this how __findattr__ is supposed, to work? Shouldn't the interpreter first check whether the attribute exists as a method name before calling __findattr__? (and if not, how do I combine __findattr__ with access to member functions?) Thanks, Jakob --- Main.java --- import org.python.core.*; import org.python.util.*; public class Main { public static void main(String[] args) { PythonInterpreter p = new PythonInterpreter(); PyObject ret; p.exec("import Test"); p.exec("a = Test()"); ret = p.eval("a.info()"); System.out.println(ret.toString()); } } --- Test.java --- import org.python.core.*; public class Test extends PyObject { public PyObject __findattr__(String s) { return null; } public String info() { return "info"; } } |
From: <bc...@wo...> - 2001-12-12 16:41:23
|
[Jakob Svensson] >sorry for these repeated questions about __findattr__, but I just can't get >it to work properly. When I define __findattr__(String s) in my Java class, >I will get attribute errors for method calls from Jython on all methods in >my Java class. In the following example, which consists of two small files, >I will get > > AttributeError: instance of 'Test' has no attribute 'info' > >Is this how __findattr__ is supposed, to work? Yes. >Shouldn't the interpreter >first check whether the attribute exists as a method name before calling >__findattr__? No. >(and if not, how do I combine __findattr__ with access to >member functions?) The code "a.info()" get compiled into the call: a.invoke("info") Where "invoke" is defined in PyObject as: public PyObject invoke(String name) { PyObject f = __getattr__(name); return f.__call__(); } and __getattr__ is defined as: public final PyObject __getattr__(PyString name) { PyObject ret = __findattr__(name); if (ret == null) throw Py.AttributeError(safeRepr() + " has no attribute '" + name + "'"); return ret; } So it is not at all surprising that you get an AttributeError. The default implementation of __findattr__ in PyObject already support lookup in the class and binding of functions. A common implementation of __findattr__ in PyObject subclasses looks something like this: public PyObject __findattr__(String name) { if (name == "foobar") return Py.newString("foobar"); return super.__findattr__(name); } First intercept the names that your object can answer for and then pass the request to the class to resolve methods. regards, finn |