You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<li>The <code>build_match_and_apply_functions()</code> function has not changed. You’re still using closures to build two functions dynamically that use variables defined in the outer function.
282
282
<li>The global <code>open()</code> function opens a file and returns a file object. In this case, the file we’re opening contains the pattern strings for pluralizing nouns. The <code>with</code> statement creates what’s called a <i>context</i>: when the <code>with</code> block ends, Python will automatically close the file, even if an exception is raised inside the <code>with</code> block. You’ll learn more about <code>with</code> blocks and file objects in the <ahref=files.html>Files</a> chapter.
283
283
<li>The <code>for line in <fileobject></code> idiom reads data from the open file, one line at a time, and assigns the text to the <var>line</var> variable. You’ll learn more about reading from files in the <ahref=files.html>Files</a> chapter.
284
-
<li>Each line in the file really has three values, but they’re separated by whitespace (tabs or spaces, it makes no difference). To split it out, use the <code>split()</code> string method. The first argument to the <code>split()</code> method is <code>None</code>, which means “split on any whitespace (tabs or spaces, it makes no difference).” The second argument is <code>3</code>, which means “split on whitespace 3 times, then leave the rest of the line alone.” A line like <code>[sxz]$ $ es</code> will be broken up into the list <code>['[sxz]$', '$', 'es']</code>, which means that <var>pattern</var> will get <code>'[sxz]$'</code>, <var>search</var> will get <code>'$'</code>, and <var>replace</var> will get <code>'es'</code>. That’s a lot of power in one little line of code.
284
+
<li>Each line in the file really has three values, but they’re separated by whitespace (tabs or spaces, it makes no difference). To split it out, use the <code>split()</code> string method. The first argument to the <code>split()</code> method is <code>None</code>, which means “split on any whitespace (tabs or spaces, it makes no difference).” The second argument is <code>2</code>, which means “split on whitespace 2 times (splitting once returns two values, splitting twice returns three values, and so on), then leave the rest of the line alone.” A line like <code>[sxz]$ $ es</code> will be broken up into the list <code>['[sxz]$', '$', 'es']</code>, which means that <var>pattern</var> will get <code>'[sxz]$'</code>, <var>search</var> will get <code>'$'</code>, and <var>replace</var> will get <code>'es'</code>. That’s a lot of power in one little line of code.
285
285
<li>Finally, you pass <code>pattern</code>, <code>search</code>, and <code>replace</code> to the <code>build_match_and_apply_functions()</code> function, which returns a tuple of functions. You append this tuple to the <var>rules</var> list, and <var>rules</var> ends up storing the list of match and apply functions that the <code>plural()</code> function expects.
raise ValueError('no matching rule for {0}'.format(noun))</code></pre>
388
388
<ol>
389
-
<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 “columns” and assign them to three local variables.
389
+
<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, 2)</code> to get the three “columns” and assign them to three local variables.
390
390
<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>.
391
391
<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 pattern_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.
0 commit comments