[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