[C++-sig] Re: Adding __len__ to range objects
David Abrahams
dave at boost-consulting.com
Mon Aug 11 00:27:54 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?
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
More information about the Cplusplus-sig
mailing list