深入了解Python第7章:如何使用该迭代器?

深入了解Python第7章:如何使用该迭代器?,python,python-3.x,Python,Python 3.x,在第7章中,作者创建了一个迭代器,该迭代器构建了将单数英语名词转换为复数的规则: class LazyRules: rules_filename = 'plural5-rules.txt' def __init__(self): self.pattern_file = open(self.rules_filename, encoding='utf-8') self.cache = [] def

在第7章中,作者创建了一个迭代器,该迭代器构建了将单数英语名词转换为复数的规则:

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()
虽然这本书对这段代码的每一点都提供了非常清晰和透彻的解释,但它没有解释如何使用它?如何使用这些规则来更改名词

我试图在课堂上添加以下内容:

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:我根据janos的评论修改了代码。 现在看起来是这样的:

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))
现在它可以工作了!!!!谢谢你,亚诺斯

然而,我还有另一个问题:为什么在build\u match\u和\u apply\u函数中,函数matches\u ruleword有一个变量'word',而在复数函数matches\u rulenoon中,变量的名称不应该相同吗?

复数不应该是懒散规则的一种方法,而应该是一个独立的函数。它应该在规则上发布,这是自定义迭代器类LazyRules的一个实例:

复数不应该是懒散规则的一种方法,而是一种独立的功能。它应该在规则上发布,这是自定义迭代器类LazyRules的一个实例:


看起来用户需要1一个存在的文件,请参见规则\文件名,2来迭代规则,从而导致对文件的迭代。该迭代器对于遵循迭代器协议有点粗略,因为每次调用iter时它都会重置自身。这将可怕地破坏规则中x的相同迭代器上的嵌套循环:规则中y的相同迭代器上的嵌套循环:随便什么。我建议将cache和file对象设置为类变量,并在uuu init_uuu中将索引设置为零。然后,您可以在任何时候创建一个新实例,您可以从头开始。看起来用户需要1个存在的文件,请参见规则\u文件名,2来迭代规则,这反过来会导致对该文件的迭代。该迭代器对于遵循迭代器协议有点粗略,因为每次你调用iter它都会自动复位。这将可怕地破坏规则中x的相同迭代器上的嵌套循环:规则中y的相同迭代器上的嵌套循环:随便什么。我建议将cache和file对象设置为类变量,并在uuu init_uuu中将索引设置为零。然后,您可以在任何时候重新开始创建一个新实例。
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))