Skip to main content
 首页 » 编程设计

python之Dive into Python 3 中的示例代码

2025年05月04日11wayfarer

我正在阅读 Mark Pilgrim 的 Dive into Python 3。他给出了名词复数化的“必杀技”代码。我的问题是:第 30 和 31 行的代码是否必要?没有它们,程序似乎运行良好。添加它们有什么好处?谢谢

    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)) 
 
class LazyRules: 
    rules_filename = 'plural6-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] 
 
##Line 30:        if self.pattern_file.closed: 
##Line 31:            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() 
nouns=['fox', 'horse', 'cheetah','ad', 'quay', 'vacancy'] 
for noun in nouns: 
    print (noun) 
    print(plural(noun)+'\n') 
 
## plural6-rules.txt: 
##[sxz]$ $ es 
##[^aeioudgkprt]h$ $ es 
##[^aeiou]y$ y$ ies 
##$   $   s 

请您参考如下方法:

是的,这些行是必需的,因为 book explains (见注释 2)。

在之前的迭代中,模式文件可能已经关闭。

通过启动 StopIteration,for 循环将正常退出(参见 note 5)

如果您不raise StopIteration,下一行将尝试从关闭的文件中读取。

line = self.pattern_file.readline() 

这会导致 ValueError。

为了演示这些行何时运行,请尝试删除 plural6-rules.txt 文件的最后一行(匹配所有内容),然后键入以下内容。

>>> from plural6 import plural 
>>> plural("fox") # matches the first rule 
'foxes' 
>>> plural("foo") # does not match any rules. file is closed. 
>>> plural("foo") # We have removed the check, we will try to read from a closed file 
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
  File "plural6.py", line 50, in plural 
    for matches_rule, apply_rule in rules: 
  File "plural6.py", line 36, in __next__ 
    line = self.pattern_file.readline() 
ValueError: I/O operation on closed file.