mirror of
https://github.com/boostorg/python.git
synced 2026-01-20 16:52:15 +00:00
102 lines
7.5 KiB
HTML
102 lines
7.5 KiB
HTML
<html>
|
|
<head>
|
|
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
|
<title>Iterators</title>
|
|
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
|
<link rel="prev" href="using_the_interpreter.html">
|
|
<link rel="next" href="exception_translation.html">
|
|
</head>
|
|
<body>
|
|
<table width="100%" height="48" border="0" cellspacing="2">
|
|
<tr>
|
|
<td><img src="theme/c%2B%2Bboost.gif">
|
|
</td>
|
|
<td width="85%">
|
|
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Iterators</b></font>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table border="0">
|
|
<tr>
|
|
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
|
<td width="30"><a href="using_the_interpreter.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
|
<td width="20"><a href="exception_translation.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
|
</tr>
|
|
</table>
|
|
<p>
|
|
In C++, and STL in particular, we see iterators everywhere. Python also has
|
|
iterators, but these are two very different beasts.</p>
|
|
<p>
|
|
<b>C++ iterators:</b></p>
|
|
<ul><li>C++ has 5 type categories (random-access, bidirectional, forward, input, output)</li><li>There are 2 Operation categories: reposition, access</li><li>A pair of iterators is needed to represent a (first/last) range.</li></ul><p>
|
|
<b>Python Iterators:</b></p>
|
|
<ul><li>1 category (forward)</li><li>1 operation category (next())</li><li>Raises StopIteration exception at end</li></ul><p>
|
|
The typical Python iteration protocol: <tt><b>for y in x...</b></tt> is as follows:</p>
|
|
<code><pre>
|
|
<span class=identifier>iter </span><span class=special>= </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__iter__</span><span class=special>() </span>##<span class=identifier>get </span><span class=identifier>iterator
|
|
</span><span class=keyword>try</span><span class=special>:
|
|
</span><span class=keyword>while </span><span class=number>1</span><span class=special>:
|
|
</span><span class=identifier>y </span><span class=special>= </span><span class=identifier>iter</span><span class=special>.</span><span class=identifier>next</span><span class=special>() </span>##<span class=identifier>get </span><span class=identifier>each </span><span class=identifier>item
|
|
</span><span class=special>... </span>##<span class=identifier>process </span><span class=identifier>y
|
|
</span><span class=identifier>except </span><span class=identifier>StopIteration</span><span class=special>: </span><span class=identifier>pass </span>##<span class=identifier>iterator </span><span class=identifier>exhausted
|
|
</span></pre></code>
|
|
<p>
|
|
Boost.Python provides some mechanisms to make C++ iterators play along
|
|
nicely as Python iterators. What we need to do is to produce
|
|
appropriate __iter__ function from C++ iterators that is compatible
|
|
with the Python iteration protocol. For example:</p>
|
|
<code><pre>
|
|
<span class=identifier>object </span><span class=identifier>get_iterator </span><span class=special>= </span><span class=identifier>iterator</span><span class=special><</span><span class=identifier>vector</span><span class=special><</span><span class=keyword>int</span><span class=special>> >();
|
|
</span><span class=identifier>object </span><span class=identifier>iter </span><span class=special>= </span><span class=identifier>get_iterator</span><span class=special>(</span><span class=identifier>v</span><span class=special>);
|
|
</span><span class=identifier>object </span><span class=identifier>first </span><span class=special>= </span><span class=identifier>iter</span><span class=special>.</span><span class=identifier>next</span><span class=special>();
|
|
</span></pre></code>
|
|
<p>
|
|
Or for use in class_<>:</p>
|
|
<code><pre>
|
|
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>"__iter__"</span><span class=special>, </span><span class=identifier>iterator</span><span class=special><</span><span class=identifier>vector</span><span class=special><</span><span class=keyword>int</span><span class=special>> >())
|
|
</span></pre></code>
|
|
<p>
|
|
<b>range</b></p>
|
|
<p>
|
|
We can create a Python savvy iterator using the range function:</p>
|
|
<ul><li>range(start, finish)</li><li>range<Policies,Target>(start, finish)</li></ul><p>
|
|
Here, start/finish may be one of:</p>
|
|
<ul><li>member data pointers</li><li>member function pointers</li><li>adaptable function object (use Target parameter)</li></ul><p>
|
|
<b>iterator</b></p>
|
|
<ul><li>iterator<T, Policies>()</li></ul><p>
|
|
Given a container <tt>T</tt>, iterator is a shortcut that simply calls <tt>range</tt>
|
|
with &T::begin, &T::end.</p>
|
|
<p>
|
|
Let's put this into action... Here's an example from some hypothetical
|
|
bogon Particle accelerator code:</p>
|
|
<code><pre>
|
|
<span class=identifier>f </span><span class=special>= </span><span class=identifier>Field</span><span class=special>()
|
|
</span><span class=keyword>for </span><span class=identifier>x </span><span class=identifier>in </span><span class=identifier>f</span><span class=special>.</span><span class=identifier>pions</span><span class=special>:
|
|
</span><span class=identifier>smash</span><span class=special>(</span><span class=identifier>x</span><span class=special>)
|
|
</span><span class=keyword>for </span><span class=identifier>y </span><span class=identifier>in </span><span class=identifier>f</span><span class=special>.</span><span class=identifier>bogons</span><span class=special>:
|
|
</span><span class=identifier>count</span><span class=special>(</span><span class=identifier>y</span><span class=special>)
|
|
</span></pre></code>
|
|
<p>
|
|
Now, our C++ Wrapper:</p>
|
|
<code><pre>
|
|
<span class=identifier>class_</span><span class=special><</span><span class=identifier>F</span><span class=special>>(</span><span class=string>"Field"</span><span class=special>)
|
|
.</span><span class=identifier>property</span><span class=special>(</span><span class=string>"pions"</span><span class=special>, </span><span class=identifier>range</span><span class=special>(&</span><span class=identifier>F</span><span class=special>::</span><span class=identifier>p_begin</span><span class=special>, &</span><span class=identifier>F</span><span class=special>::</span><span class=identifier>p_end</span><span class=special>))
|
|
.</span><span class=identifier>property</span><span class=special>(</span><span class=string>"bogons"</span><span class=special>, </span><span class=identifier>range</span><span class=special>(&</span><span class=identifier>F</span><span class=special>::</span><span class=identifier>b_begin</span><span class=special>, &</span><span class=identifier>F</span><span class=special>::</span><span class=identifier>b_end</span><span class=special>));
|
|
</span></pre></code>
|
|
<table border="0">
|
|
<tr>
|
|
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
|
<td width="30"><a href="using_the_interpreter.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
|
<td width="20"><a href="exception_translation.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<hr size="1"><p class="copyright">Copyright © 2002-2003 David Abrahams<br>Copyright © 2002-2003 Joel de Guzman<br><br>
|
|
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
|
is granted provided this copyright notice appears in all copies. This document
|
|
is provided "as is" without express or implied warranty, and with
|
|
no claim as to its suitability for any purpose. </font> </p>
|
|
</body>
|
|
</html>
|