[C++-sig] Re: Adding __len__ to range objects

Raoul Gough RaoulGough at yahoo.co.uk
Mon Aug 11 13:35:46 CEST 2003

abeyer at uni-osnabrueck.de writes:

>David Abrahams <dave at boost-consulting.com> writes:
>> None of the Python iterators support __len__ and I wonder if it's a
>> good idea to add it to an iterator we create.  Your thoughts?
> Raoul, I think what you actually want is a conversion from std::vector to
> python::list. That gives you the len-method as well as the __getitem__
> function. Either you register your own class with the python methods
> __iter__, __len__, __getitem__ or you use the python::list() function to
> create a 'real' python list.

Hmmmm... creating a python list from Python would be quite an
overhead, since it would have to iterate over the entire sequence,
just as manually counting the elements would (including whatever
Python to C++ interfacing overheads for each next() call).

My reasoning goes like this - the iterator-pair object is very
lightweight, and yet the basic Python iterator interface does not
expose all of it's functionality (e.g. the ability to know how far it
is from the end). In general, a python iterator might not know this,
but boost::python::range does, certainly for random_access iterators,
and much faster than any Python code could work it out for
forward_iterator or bidirectional_iterator.

> I would not change the range() function to
> return something in-between a list and an iterator. Dave, maybe a return
> value converter like range() that creates a python list from a C++ vector
> would be helpfull.

I don't really understand how the boost::python list TypeWrapper
works, but I suspect it would also have to iterate over the entire
sequence, since there doesn't seem to be any specialization of the
list constructor for random access iterators (are Python lists even
stored contiguously?)

To explain my original motivation, I was hoping to:

a) avoid exposing the entire vector from my class's interface
b) avoid making Python understand std::vector<my_instance>
c) know how long a sequence the iterator pair represents

and adding len() to range solved all of these problems at once :-)

Raoul Gough
"Let there be one measure for wine throughout our kingdom, and one
measure for ale, and one measure for corn" - Magna Carta

More information about the Cplusplus-sig mailing list