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

abeyer at uni-osnabrueck.de abeyer at uni-osnabrueck.de
Mon Aug 11 10:48:39 CEST 2003


> Raoul Gough <RaoulGough at yahoo.co.uk> writes:
>
>> I recently wanted to know how many items were in a C++ vector, which I
>> had only exposed to Python via iterator pairs (boost::python::range).
>> Currently, len(range_object) doesn't work because range doesn't
>> provide a __len__ method, but it isn't hard to add this. I did the
>> following in d:/CVS/boost/boost/boost/python/object/iterator.hpp:
>>
>> in template <...> struct iterator_range, add
>>
>>   typename std::iterator_traits<Iterator>::difference_type
>>   distance () const {
>>     return std::distance (m_start, m_finish);
>>   }
>>
>> in template <...> object demand_iterator_class (...)
>>
>>       return class_<range_>(name, no_init)
>>           .def("__iter__", identity_function())
>>           .setattr("next", next_function)
>> 	  .def("__len__", &range_::distance)
>>           ;
>>
>> and everything worked OK. This seems to me like a useful addition -
>> any comments? If it seems sensible, maybe David Abrahams could add
>> something similar to the CVS?
>
> It only works for random-access iterators.  You could fix it so that
> it would only create the __len__ function for random-access
> iterators; that would be better.
>
> Then, also, range() creates an iterator-returning function, not an
> iteratable-returning function.  There are subtle differences.
>
>     for x in some_list:
>        print x
>
>     for x in some_list:
>        print x  # prints the same elements
>
> but:
>
>     for x in some_iterator:
>        print x
>
>     for x in some_iterator:
>        print x  # prints nothing
>
> 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. 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.

    Andreas





More information about the Cplusplus-sig mailing list