From: Jeff E. <JEm...@lg...> - 2003-02-28 16:02:21
|
Here is __getitem__ from org/python/core/PyInstance.java: public PyObject __getitem__(PyObject key) { CollectionProxy proxy = getCollection(); if (proxy != CollectionProxy.NoProxy) { PyObject ret = proxy.__finditem__(key); if (ret == null) { throw Py.KeyError(key.toString()); } return ret; } PyObject ret = trySlice(key, "__getslice__", null); if (ret != null) return ret; return invoke("__getitem__", key); } You can see that the code checks whether your instance is a collection first and calls its __finditem__ before calling your __getitem__ method. You might try extending org.python.core.PyList. |
From: Ype K. <yk...@xs...> - 2003-02-28 21:02:32
|
Jeff, Justin, >Here is __getitem__ from org/python/core/PyInstance.java: > > public PyObject __getitem__(PyObject key) { > CollectionProxy proxy = getCollection(); > if (proxy != CollectionProxy.NoProxy) { > PyObject ret = proxy.__finditem__(key); > if (ret == null) { > throw Py.KeyError(key.toString()); > } > return ret; > } > > PyObject ret = trySlice(key, "__getslice__", null); > if (ret != null) > return ret; > > return invoke("__getitem__", key); > } > > >You can see that the code checks whether your instance >is a collection first and calls its __finditem__ before >calling your __getitem__ method. > >You might try extending org.python.core.PyList. You might also consider this to be a bug in Jython. Ie. it might have checked for __getslice__ first, then for __getitem__ and only when that fails, check for a Collection proxy. In case jython would use that order, it would have found your __getitem__ before checking for being a Collection. Having said that, I don't know precisily why the checks are done in the order shown, ie. there might be another reason for the current implementation. One needs to inherit from a Collection (ArrayList in this case) to get into this situation, and this is not done very frequently. Kind regards, Ype Justin's original post (because I'm cross posting to jython-dev): Hi, Trying to create a custom array structure. Ideally I would like to subclass the built in list, but it seems this feature won't be available till version 2.2 (as per CPython) so instead I am extending java.util.ArrayList as per below. This works fine, and I can access the object using standard array syntax (x[0] .. etc). However when I look under the hood / overload some of the built in methods, it appears they are different from CPython. In particular, __repr__ gets called as expected but __getitem__ does not (see below). (If I run the code in CPython 2,2, replacing ArrayList with list, it works as expected). Perhaps someone can shed some light on what is happening here. thanks! Justin from java.util import * class test(ArrayList): def __getitem__(self,i): print "__getitem__"+str(i) return ArrayList.get(self,i) def __repr__(self): print "__repr__" r="" for i in self: r=r+str(i)+chr(10) return r def main(): r=test() r.add("one") r.add("two") print r # successfully calls __repr__ print r[0] # returns the right result, but doens't call __getitem__ main() -- |