简体   繁体   中英

Dive into Python Chapter 7: How do I use this iterator?

In Chapter 7, the author creates an iterator that builds rules for transforming singular English nouns into plurals:

class LazyRules:

        rules_filename = 'plural5-rules.txt'

        def __init__(self):
            self.pattern_file = open(self.rules_filename, encoding='utf-8')
            self.cache = []

        def __iter__(self):
            self.cache_index = 0
            return self

        def __next__(self):
            self.cache_index += 1
            if len(self.cache) >= self.cache_index:
                return self.cache[self.cache_index - 1]
            if self.pattern_file.closed:
                raise StopIteration
            line = self.pattern_file.readline()
            if not line:
                self.pattern_file.close()
                raise StopIteration

            pattern, search, replace = line.split(None, 3)
            funcs = build_match_and_apply_functions(
                pattern, search, replace)
            self.cache.append(funcs)
            return funcs


rules = LazyRules()

While the book provides a very clear and thorough explanation for every bit of this code, it doesn't explain how one can use it? How do I use these rules to change nouns?

I tried to add this bit to the class:

def build_match_and_apply_functions(self, pattern, search, replace):
     def matches_rule(word):
        return re.search(pattern, word)
     def apply_rule(word):
        return re.sub(search, replace, word)
     return (matches_rule, apply_rule)

def plural(self, noun):
      for matches_rule, apply_rule in self.__next__():
         if matches_rule(noun):
            return apply_rule(noun)
      raise ValueError('no matching rule for {0}'.format(noun))

Upd: I changed the code accroding to the comment from janos . So it now looks like this:

class LazyRules:
        rules_filename = 'plural5-rules.txt'

        def __init__(self):
            self.pattern_file = open(self.rules_filename, encoding='utf-8')
            self.cache = []

        def __iter__(self):
            self.cache_index = 0
            return self

        def __next__(self):
            self.cache_index += 1
            if len(self.cache) >= self.cache_index:
                return self.cache[self.cache_index - 1]
            if self.pattern_file.closed:
                raise StopIteration
            line = self.pattern_file.readline()
            if not line:
                self.pattern_file.close()
                raise StopIteration

            pattern, search, replace = line.split(None, 3)
            funcs = build_match_and_apply_functions(
                pattern, search, replace)
            self.cache.append(funcs)
            return funcs

rules = LazyRules()

import re

def build_match_and_apply_functions(pattern, search, replace):
     def matches_rule(word):
        return re.search(pattern, word)
     def apply_rule(word):
        return re.sub(search, replace, word)
     return (matches_rule, apply_rule)

def plural(noun):
      for matches_rule, apply_rule in rules:
         if matches_rule(noun):
            return apply_rule(noun)
      raise ValueError('no matching rule for {0}'.format(noun))

And it works now!!!! Thank you janos !

However, I have another question: why in build_match_and_apply_functions() function matches_rule(word) has a variable 'word' , while in the plural() function matches_rule(noun) has a variable 'noun' , shouldn't the variable be named the same?

plural should not be a method of LazyRules , but an independent function. And it should issue over rules (which is an instance of the custom iterator class LazyRules ):

def plural(self, noun):
      for matches_rule, apply_rule in rules:
         if matches_rule(noun):
            return apply_rule(noun)
      raise ValueError('no matching rule for {0}'.format(noun))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM