[PyQt] SIP - %Exception for StopIteration
Giovanni Bajo
rasky at develer.com
Wed Aug 6 16:47:36 BST 2008
On 8/6/2008 7:23 AM, Jonny Morrill wrote:
> Thank you both for your help!!
>
> @Matt:
>
> WOW! I never new that you could create an iterable object from only the
> __len__ and operator[] functions!! I must have missed that when I was
> searching through the python documentation for iterator objects. It is not
> clear to me which is quicker, the only difference seems to be that when you
> use __iter__, you can return a copy of the object so that any modifications
> will not affect the original object. Thanks again!
Actually, __iter__ shouldn't modify anything. The simplest way to
implement __iter__ in Python is to write a generator function which
yields the elements.
__len__ and __getitem__ predate __iter__ (and iterators, and generators)
by far: it is the oldest and easier way to iterate over an object in a
for loop. If you think of it, it is obvious that it is possible to do a
for-loop over an object that represents a collection and already exposes
__len__ and __getitem__.
To be specific, you don't even need __len__: it's just an optimization
exploited internally by Python. It's sufficient to have __getitem__ and
raises IndexError whenever the sequence is finished.
> @Giovanni:
>
> That seems to be exactly what I was after. I have a few questions about the
> implementation though.
>
> Since I do use the next() function as part of my C++ API i might just keep
> my iteration the way it is currently. I use it to iterate similar to the
> following code:
>
> Item* Object::next()
> {
> if(this->currentIndex < this->length) {
> return item[this->currentIndex];
> } else {
> return NULL;
> }
> }
>
> // In Code
> Object* object = new Object;
> Item* item;
> while(item = object->next()) {
> // do something with item
> }
I wouldn't call this a good design: your iteration actually does modify
the object. So you can iterate onto the object only once (or you need a
resetIteration function); the object is not thread-safe; etc.
Anyway, surely it's not what Python expects from the iteration function.
> Oh!! So the %MethodCode doesn't require a partner C++ function? You can
> specify python specific functions inside it??
Yes. Given the code you showed me, probably it's sufficient something
like this in the sip file (pseudo-code, untest):
class Object
{
Item* __getitem__(int);
%MethodCode
if (a0 >= sipCpp->length)
{
PyErr_SetNone(PyExc_IndexError);
sipIsErr = 1;
}
else
{
Item *item = sipCpp->items[a0];
sipResult = sipConvertToInstance([...]);
}
%End
}
I'll let you find out the details of how to write the code. Refer to the
SIP documentation.
--
Giovanni Bajo
Develer S.r.l.
http://www.develer.com
More information about the PyQt
mailing list