[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