fix typo and add note about using with instead of try..finally [h/t P.P.]

This commit is contained in:
Mark Pilgrim
2009-04-18 11:19:07 -04:00
parent 35cbc5f288
commit 99b7b12b74
+2 -1
View File
@@ -252,6 +252,7 @@ $ $ s</code></pre>
<p>Now let&#8217;s see how you can use this rules file.
<p>[FIXME: now that this chapter comes before the I/O chapter, need to at least mention what open() does]
<p>[FIXME: try/finally -> with]
<p class=d>[<a href=examples/plural4.py>download <code>plural4.py</code></a>]
<pre><code>import re
@@ -371,7 +372,7 @@ def plural(noun):
if matches_rule(noun):
return apply_rule(noun)</code></pre>
<ol>
<li>As you&#8217;ve seen, <code>for line in open(...)</code> is a common idiom for reading from a file one line at a time. But here&#8217;s what you might not know: the reason this idiom works is because <em><code>open()</code> actually returns a generator, and calling <code>next()</code> on this generator returns the next line of the file.</em>
<li>As you&#8217;ve seen, <code>for line in open(...)</code> is a common idiom for reading from a file one line at a time. But here&#8217;s what you might not know: the reason this idiom works is because <em><code>open()</code> actually returns an iterator, and calling <code>next()</code> on this iterator returns the next line of the file.</em>
<li>No magic here. Remember that the lines of the rules file have three values separated by whitespace, so you use <code>line.split(None, 3)</code> to get the three &#8220;columns&#8221; and assign them to three local variables.
<li><em>And then you yield.</em> What do you yield? Two functions, built dynamically with your old friend, <code>build_match_and_apply_functions()</code>, which is identical to the previous examples. In other words, <code>rules()</code> is a generator that spits out match and apply functions <em>on demand</em>.
<li>Since <code>rules()</code> is a generator, you can use it directly in a <code>for</code> loop. The first time through the <code>for</code> loop, you will call the <code>rules()</code> function, which will open the pattern file, read the first line, dynamically build a match function and an apply function from the patterns on that line, and yield the dynamically built functions. The second time through the <code>for</code> loop, you will pick up exactly where you left off in <code>rules()</code> (which was in the middle of the <code>for line in file(...)</code> loop). The first thing it will do is read the next line of the file (which is still open), dynamically build another match and apply function based on the patterns on that line in the file, and yield the two functions.