diff --git a/examples/plural5.py b/examples/plural5.py index 31e192a..0a552c1 100644 --- a/examples/plural5.py +++ b/examples/plural5.py @@ -14,14 +14,14 @@ def build_match_and_apply_functions(pattern, search, replace): return re.sub(search, replace, word) return [matches_rule, apply_rule] -def rules(): - with open('plural5-rules.txt') as pattern_file: +def rules(rules_filename): + with open(rules_filename) as pattern_file: for line in pattern_file: pattern, search, replace = line.split(None, 3) yield build_match_and_apply_functions(pattern, search, replace) -def plural(noun): - for matches_rule, apply_rule in rules(): +def plural(noun, rules_filename='plural5-rules.txt'): + for matches_rule, apply_rule in rules(rules_filename): if matches_rule(noun): return apply_rule(noun) raise ValueError('no matching rule for {0}'.format(noun)) diff --git a/generators.html b/generators.html index 17ac5c5..56a6e2d 100644 --- a/generators.html +++ b/generators.html @@ -375,20 +375,21 @@ def plural(noun):
Let’s go back to plural5.py and see how this version of the plural() function works.
-
def rules():
- with open('plural5-rules.txt') as pattern_file:
+def rules(rules_filename):
+ with open(rules_filename) as pattern_file:
for line in pattern_file:
- pattern, search, replace = line.split(None, 3) ②
- yield build_match_and_apply_functions(pattern, search, replace) ③
+ pattern, search, replace = line.split(None, 3) ①
+ yield build_match_and_apply_functions(pattern, search, replace) ②
-def plural(noun):
- for matches_rule, apply_rule in rules(): ④
+def plural(noun, rules_filename='plural5-rules.txt'):
+ for matches_rule, apply_rule in rules(rules_filename): ③
if matches_rule(noun):
- return apply_rule(noun)
+ return apply_rule(noun)
+ raise ValueError('no matching rule for {0}'.format(noun))
line.split(None, 3) to get the three “columns” and assign them to three local variables.
build_match_and_apply_functions(), which is identical to the previous examples. In other words, rules() is a generator that spits out match and apply functions on demand.
-rules() is a generator, you can use it directly in a for loop. The first time through the for loop, you will call the rules() 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 for loop, you will pick up exactly where you left off in rules() (which was in the middle of the for line in file(...) 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.
+rules() is a generator, you can use it directly in a for loop. The first time through the for loop, you will call the rules() 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 for loop, you will pick up exactly where you left off in rules() (which was in the middle of the for line in pattern_file 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.
What have you gained over stage 4? Startup time. In stage 4, when you imported the plural4 module, it read the entire patterns file and built a list of all the possible rules, before you could even think about calling the plural() function. With generators, you can do everything lazily: you read the first rule and create functions and try them, and if that works you don’t ever read the rest of the file or create any other functions.